From a6264b39d1a6b2498463e6b9deb4702a17373dfa Mon Sep 17 00:00:00 2001 From: Perfare Date: Tue, 16 Jul 2019 13:21:32 +0800 Subject: [PATCH] improved morph export --- AssetStudio/IImported.cs | 21 +- AssetStudioFBX/AssetStudioFBX.h | 8 +- AssetStudioFBX/AssetStudioFBXExporter.cpp | 226 ++++-------------- AssetStudioGUI/ExportOptions.Designer.cs | 31 +-- AssetStudioGUI/ExportOptions.cs | 2 - AssetStudioGUI/Exporter.cs | 3 +- .../Properties/Settings.Designer.cs | 12 - AssetStudioGUI/Properties/Settings.settings | 3 - AssetStudioGUI/app.config | 3 - AssetStudioUtility/ModelConverter.cs | 81 +++---- AssetStudioUtility/ModelExporter.cs | 4 +- 11 files changed, 110 insertions(+), 284 deletions(-) diff --git a/AssetStudio/IImported.cs b/AssetStudio/IImported.cs index 2314c56..05578af 100644 --- a/AssetStudio/IImported.cs +++ b/AssetStudio/IImported.cs @@ -246,18 +246,27 @@ namespace AssetStudio public class ImportedMorph { public string Path { get; set; } - public string ClipName { get; set; } - public List> Channels { get; set; } + public List Channels { get; set; } + } + + public class ImportedMorphChannel + { + public string Name { get; set; } public List KeyframeList { get; set; } - public List MorphedVertexIndices { get; set; } } public class ImportedMorphKeyframe { - public string Name { get; set; } - public List VertexList { get; set; } - public List MorphedVertexIndices { get; set; } + public bool hasNormals { get; set; } + public bool hasTangents { get; set; } public float Weight { get; set; } + public List VertexList { get; set; } + } + + public class ImportedMorphVertex + { + public uint Index { get; set; } + public ImportedVertex Vertex { get; set; } } public static class ImportedHelpers diff --git a/AssetStudioFBX/AssetStudioFBX.h b/AssetStudioFBX/AssetStudioFBX.h index 23f2a66..ac9882b 100644 --- a/AssetStudioFBX/AssetStudioFBX.h +++ b/AssetStudioFBX/AssetStudioFBX.h @@ -48,7 +48,7 @@ namespace AssetStudio { ref class Exporter { public: - static void Export(String^ name, IImported^ imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii); + static void Export(String^ name, IImported^ imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii); private: bool exportSkins; @@ -77,9 +77,9 @@ namespace AssetStudio { void ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame); void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList); FbxFileTexture* ExportTexture(ImportedTexture^ matTex); - void ExportAnimations(bool eulerFilter, float filterValue, bool flatInbetween); - void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision, bool flatInbetween); - void ExportMorphs(bool morphMask, bool flatInbetween); + void ExportAnimations(bool eulerFilter, float filterValue); + void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision); + void ExportMorphs(); }; }; } diff --git a/AssetStudioFBX/AssetStudioFBXExporter.cpp b/AssetStudioFBX/AssetStudioFBXExporter.cpp index 846d51a..d515912 100644 --- a/AssetStudioFBX/AssetStudioFBXExporter.cpp +++ b/AssetStudioFBX/AssetStudioFBXExporter.cpp @@ -2,7 +2,7 @@ namespace AssetStudio { - void Fbx::Exporter::Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii) + void Fbx::Exporter::Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii) { FileInfo^ file = gcnew FileInfo(path); DirectoryInfo^ dir = file->Directory; @@ -14,8 +14,8 @@ namespace AssetStudio Directory::SetCurrentDirectory(dir->FullName); auto name = Path::GetFileName(path); Exporter^ exporter = gcnew Exporter(name, imported, allFrames, allBones, skins, boneSize, scaleFactor, versionIndex, isAscii); - //TODO exporter->ExportMorphs(false, flatInbetween); - exporter->ExportAnimations(eulerFilter, filterPrecision, flatInbetween); + exporter->ExportMorphs(); + exporter->ExportAnimations(eulerFilter, filterPrecision); exporter->pExporter->Export(exporter->pScene); delete exporter; @@ -629,7 +629,7 @@ namespace AssetStudio prop.ConnectSrcObject(pTexture); } - void Fbx::Exporter::ExportAnimations(bool eulerFilter, float filterPrecision, bool flatInbetween) + void Fbx::Exporter::ExportAnimations(bool eulerFilter, float filterPrecision) { auto importedAnimationList = imported->AnimationList; if (importedAnimationList == nullptr) @@ -656,11 +656,11 @@ namespace AssetStudio { kTakeName = FbxString("Take") + FbxString(i); } - ExportKeyframedAnimation(importedAnimation, kTakeName, lFilter, filterPrecision, flatInbetween); + ExportKeyframedAnimation(importedAnimation, kTakeName, lFilter, filterPrecision); } } - void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision, bool flatInbetween) + void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision) { List^ pAnimationList = parser->TrackList; @@ -753,206 +753,60 @@ namespace AssetStudio } } - void Fbx::Exporter::ExportMorphs(bool morphMask, bool flatInbetween) + void Fbx::Exporter::ExportMorphs() { - /*if (imported->MeshList == nullptr) + if (imported->MeshList == nullptr) { return; } - - for (int meshIdx = 0; meshIdx < imported->MeshList->Count; meshIdx++) + for each (ImportedMorph^ morph in imported->MorphList) { - ImportedMesh^ meshList = imported->MeshList[meshIdx]; - FbxNode* pBaseNode = NULL; - for (int nodeIdx = 0; nodeIdx < pMeshNodes->GetCount(); nodeIdx++) + auto frame = imported->RootFrame->FindFrameByPath(morph->Path); + if (frame != nullptr) { - FbxNode* pMeshNode = pMeshNodes->GetAt(nodeIdx); - String^ framePath = gcnew String(pMeshNode->GetName()); - FbxNode* rootNode = pMeshNode; - while ((rootNode = rootNode->GetParent()) != pScene->GetRootNode()) - { - framePath = gcnew String(rootNode->GetName()) + "/" + framePath; - } - if (framePath == meshList->Path) - { - pBaseNode = pMeshNode; - break; - } - } - if (pBaseNode == NULL) - { - continue; - } + FbxNode* pNode = (FbxNode*)frameToNode[frame]; + FbxMesh* pMesh = pNode->GetMesh(); - for each (ImportedMorph^ morph in imported->MorphList) - { - if (morph->Path != meshList->Path) - { - continue; - } + FbxBlendShape* lBlendShape = FbxBlendShape::Create(pScene, pNode->GetName()); + pMesh->AddDeformer(lBlendShape); - int meshVertexIndex = 0; - for (int meshObjIdx = pBaseNode->GetChildCount() - meshList->SubmeshList->Count; meshObjIdx < meshList->SubmeshList->Count; meshObjIdx++) + for (int i = 0; i < morph->Channels->Count; i++) { - List^ vertList = meshList->SubmeshList[meshObjIdx]->VertexList; - FbxNode* pBaseMeshNode = pBaseNode->GetChild(meshObjIdx); - FbxMesh* pBaseMesh = pBaseMeshNode->GetMesh(); - int numColourSets = pBaseMesh->GetElementVertexColorCount(); + auto channel = morph->Channels[i]; - FbxBlendShape* lBlendShape; + FbxBlendShapeChannel* lBlendShapeChannel; WITH_MARSHALLED_STRING ( - pShapeName, - morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty), - lBlendShape = FbxBlendShape::Create(pScene, pShapeName); + pChannelName, + channel->Name, + lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, pChannelName); ); - FbxProperty rootGroupProp = FbxProperty::Create(lBlendShape, FbxStringDT, "RootGroup"); - pBaseMesh->AddDeformer(lBlendShape); - List^ keyframes = morph->KeyframeList; - for (int i = 0; i < morph->Channels->Count; i++) + lBlendShape->AddBlendShapeChannel(lBlendShapeChannel); + + for each(ImportedMorphKeyframe^ keyframe in channel->KeyframeList) { - FbxBlendShapeChannel* lBlendShapeChannel; - if (!flatInbetween) + FbxShape* lShape = FbxShape::Create(pScene, ""); + lBlendShapeChannel->AddTargetShape(lShape, keyframe->Weight); + + auto vectorCount = pMesh->GetControlPointsCount(); + FbxVector4* orilVector4 = pMesh->GetControlPoints(); + lShape->InitControlPoints(vectorCount); + FbxVector4* lVector4 = lShape->GetControlPoints(); + + for (int j = 0; j < vectorCount; j++) { - WITH_MARSHALLED_STRING - ( - pChannelName, - gcnew String(lBlendShape->GetName()) + "." + keyframes[morph->Channels[i]->Item2]->Name->Substring(0, keyframes[morph->Channels[i]->Item2]->Name->LastIndexOf("_")), - lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, pChannelName); - ); - lBlendShapeChannel->DeformPercent = morph->Channels[i]->Item1; - lBlendShape->AddBlendShapeChannel(lBlendShapeChannel); + auto vertex = orilVector4[j]; + lVector4[j] = FbxVector4(vertex); } - - for (int frameIdx = 0; frameIdx < morph->Channels[i]->Item3; frameIdx++) + for (int j = 0; j < keyframe->VertexList->Count; j++) { - int shapeIdx = morph->Channels[i]->Item2 + frameIdx; - ImportedMorphKeyframe^ keyframe = keyframes[shapeIdx]; - - FbxShape* pShape; - if (!flatInbetween) - { - char* pMorphShapeName; - try - { - pMorphShapeName = StringToCharArray(keyframe->Name); - if (pScene->FindMember(pMorphShapeName)) - { - Marshal::FreeHGlobal((IntPtr)pMorphShapeName); - pMorphShapeName = StringToCharArray(morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty) + "__" + keyframe->Name); - } - pShape = FbxShape::Create(pScene, pMorphShapeName); - } - finally - { - Marshal::FreeHGlobal((IntPtr)pMorphShapeName); - } - if (frameIdx == morph->Channels[i]->Item3 - 1) - { - FbxProperty::Create(lBlendShape, FbxStringDT, rootGroupProp.GetName() + "|" + pShape->GetName()); - } - lBlendShapeChannel->AddTargetShape(pShape, keyframe->Weight); - } - else - { - lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, ""); - lBlendShapeChannel->DeformPercent = morph->Channels[i]->Item1; - lBlendShape->AddBlendShapeChannel(lBlendShapeChannel); - - WITH_MARSHALLED_STRING - ( - pMorphShapeName, - morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty) + "." + keyframe->Name, - pShape = FbxShape::Create(pScene, pMorphShapeName); - ); - lBlendShapeChannel->AddTargetShape(pShape, 100); - - FbxProperty weightProp; - WITH_MARSHALLED_STRING - ( - pWeightName, - gcnew String(pShape->GetName()) + ".Weight", - weightProp = FbxProperty::Create(pBaseMesh, FbxDoubleDT, pWeightName); - ); - weightProp.ModifyFlag(FbxPropertyFlags::eUserDefined, true); - weightProp.Set(keyframe->Weight); - } - - pShape->InitControlPoints(vertList->Count); - FbxVector4* pControlPoints = pShape->GetControlPoints(); - - for (int j = 0; j < vertList->Count; j++) - { - ImportedVertex^ vertex = vertList[j]; - Vector3 coords = vertex->Position; - pControlPoints[j] = FbxVector4(coords.X, coords.Y, coords.Z, 0); - } - List^ meshIndices = keyframe->MorphedVertexIndices; - for (int j = 0; j < meshIndices->Count; j++) - { - int controlPointIndex = meshIndices[j] - meshVertexIndex; - if (controlPointIndex >= 0 && controlPointIndex < vertList->Count) - { - Vector3 coords = keyframe->VertexList[j]->Position; - pControlPoints[controlPointIndex] = FbxVector4(coords.X, coords.Y, coords.Z, 0); - } - } - if (flatInbetween && meshIndices->Count == 0) - { - Vector3 coords = vertList[0]->Position; - pControlPoints[0] = FbxVector4(coords.X - 1.0e-6, coords.Y, coords.Z, 0); - } - - if (flatInbetween && frameIdx > 0) - { - int shapeIdx = morph->Channels[i]->Item2 + frameIdx - 1; - ImportedMorphKeyframe^ keyframe = keyframes[shapeIdx]; - - List^ meshIndices = keyframe->MorphedVertexIndices; - for (int j = 0; j < meshIndices->Count; j++) - { - int controlPointIndex = meshIndices[j] - meshVertexIndex; - if (controlPointIndex >= 0 && controlPointIndex < vertList->Count) - { - Vector3 coords = keyframe->VertexList[j]->Position - vertList[controlPointIndex]->Position; - pControlPoints[controlPointIndex] -= FbxVector4(coords.X, coords.Y, coords.Z, 0); - } - } - } - - if (morphMask && frameIdx == 0) - { - int colourSetIdx = numColourSets + shapeIdx; - FbxGeometryElementVertexColor* lGeometryElementVertexColor = pBaseMesh->GetElementVertexColor(colourSetIdx); - if (lGeometryElementVertexColor == NULL) - { - lGeometryElementVertexColor = pBaseMesh->CreateElementVertexColor(); - } - lGeometryElementVertexColor->SetMappingMode(FbxGeometryElement::eByControlPoint); - lGeometryElementVertexColor->SetReferenceMode(FbxGeometryElement::eDirect); - WITH_MARSHALLED_STRING - ( - pColourLayerName, morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty) + "." + keyframe->Name, - lGeometryElementVertexColor->SetName(pColourLayerName); - ); - for (int j = 0; j < vertList->Count; j++) - { - lGeometryElementVertexColor->GetDirectArray().Add(FbxColor(1, 1, 1)); - } - for (int j = 0; j < meshIndices->Count; j++) - { - int controlPointIndex = meshIndices[j] - meshVertexIndex; - if (controlPointIndex >= 0 && controlPointIndex < vertList->Count) - { - lGeometryElementVertexColor->GetDirectArray().SetAt(controlPointIndex, FbxColor(0, 0, 1)); - } - } - } + auto index = keyframe->VertexList[j]->Index; + auto coords = keyframe->VertexList[j]->Vertex->Position; + lVector4[index] = FbxVector4(coords.X, coords.Y, coords.Z, 0); } } - meshVertexIndex += meshList->SubmeshList[meshObjIdx]->VertexList->Count; } } - }*/ + } } } \ No newline at end of file diff --git a/AssetStudioGUI/ExportOptions.Designer.cs b/AssetStudioGUI/ExportOptions.Designer.cs index fd95457..2b7a7be 100644 --- a/AssetStudioGUI/ExportOptions.Designer.cs +++ b/AssetStudioGUI/ExportOptions.Designer.cs @@ -44,7 +44,6 @@ this.label4 = new System.Windows.Forms.Label(); this.fbxVersion = new System.Windows.Forms.ComboBox(); this.label3 = new System.Windows.Forms.Label(); - this.flatInbetween = new System.Windows.Forms.CheckBox(); this.boneSize = new System.Windows.Forms.NumericUpDown(); this.label2 = new System.Windows.Forms.Label(); this.skins = new System.Windows.Forms.CheckBox(); @@ -63,7 +62,7 @@ // // OKbutton // - this.OKbutton.Location = new System.Drawing.Point(321, 267); + this.OKbutton.Location = new System.Drawing.Point(321, 244); this.OKbutton.Name = "OKbutton"; this.OKbutton.Size = new System.Drawing.Size(75, 21); this.OKbutton.TabIndex = 6; @@ -74,7 +73,7 @@ // Cancel // this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.Cancel.Location = new System.Drawing.Point(402, 267); + this.Cancel.Location = new System.Drawing.Point(402, 244); this.Cancel.Name = "Cancel"; this.Cancel.Size = new System.Drawing.Size(75, 21); this.Cancel.TabIndex = 7; @@ -170,7 +169,6 @@ this.groupBox2.Controls.Add(this.label4); this.groupBox2.Controls.Add(this.fbxVersion); this.groupBox2.Controls.Add(this.label3); - this.groupBox2.Controls.Add(this.flatInbetween); this.groupBox2.Controls.Add(this.boneSize); this.groupBox2.Controls.Add(this.label2); this.groupBox2.Controls.Add(this.skins); @@ -181,7 +179,7 @@ this.groupBox2.Controls.Add(this.eulerFilter); this.groupBox2.Location = new System.Drawing.Point(12, 12); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(214, 276); + this.groupBox2.Size = new System.Drawing.Size(214, 255); this.groupBox2.TabIndex = 11; this.groupBox2.TabStop = false; this.groupBox2.Text = "Fbx"; @@ -221,7 +219,7 @@ this.fbxFormat.Items.AddRange(new object[] { "Binary", "Ascii"}); - this.fbxFormat.Location = new System.Drawing.Point(75, 207); + this.fbxFormat.Location = new System.Drawing.Point(77, 186); this.fbxFormat.Name = "fbxFormat"; this.fbxFormat.Size = new System.Drawing.Size(61, 20); this.fbxFormat.TabIndex = 18; @@ -229,7 +227,7 @@ // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(4, 210); + this.label4.Location = new System.Drawing.Point(6, 189); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(59, 12); this.label4.TabIndex = 17; @@ -246,7 +244,7 @@ "7.3", "7.4", "7.5"}); - this.fbxVersion.Location = new System.Drawing.Point(75, 236); + this.fbxVersion.Location = new System.Drawing.Point(77, 215); this.fbxVersion.Name = "fbxVersion"; this.fbxVersion.Size = new System.Drawing.Size(47, 20); this.fbxVersion.TabIndex = 16; @@ -254,22 +252,12 @@ // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(4, 239); + this.label3.Location = new System.Drawing.Point(6, 218); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(65, 12); this.label3.TabIndex = 15; this.label3.Text = "FBXVersion"; // - // flatInbetween - // - this.flatInbetween.AutoSize = true; - this.flatInbetween.Location = new System.Drawing.Point(6, 182); - this.flatInbetween.Name = "flatInbetween"; - this.flatInbetween.Size = new System.Drawing.Size(102, 16); - this.flatInbetween.TabIndex = 12; - this.flatInbetween.Text = "FlatInbetween"; - this.flatInbetween.UseVisualStyleBackColor = true; - // // boneSize // this.boneSize.Location = new System.Drawing.Point(65, 128); @@ -345,6 +333,8 @@ // allFrames // this.allFrames.AutoSize = true; + this.allFrames.Checked = true; + this.allFrames.CheckState = System.Windows.Forms.CheckState.Checked; this.allFrames.Location = new System.Drawing.Point(6, 61); this.allFrames.Name = "allFrames"; this.allFrames.Size = new System.Drawing.Size(78, 16); @@ -370,7 +360,7 @@ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.Cancel; - this.ClientSize = new System.Drawing.Size(490, 301); + this.ClientSize = new System.Drawing.Size(490, 277); this.Controls.Add(this.groupBox2); this.Controls.Add(this.groupBox1); this.Controls.Add(this.Cancel); @@ -408,7 +398,6 @@ private System.Windows.Forms.CheckBox convertAudio; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.GroupBox groupBox2; - private System.Windows.Forms.CheckBox flatInbetween; private System.Windows.Forms.NumericUpDown boneSize; private System.Windows.Forms.Label label2; private System.Windows.Forms.CheckBox skins; diff --git a/AssetStudioGUI/ExportOptions.cs b/AssetStudioGUI/ExportOptions.cs index f23d9aa..03d8742 100644 --- a/AssetStudioGUI/ExportOptions.cs +++ b/AssetStudioGUI/ExportOptions.cs @@ -33,7 +33,6 @@ namespace AssetStudioGUI skins.Checked = (bool)Properties.Settings.Default["skins"]; boneSize.Value = (decimal)Properties.Settings.Default["boneSize"]; scaleFactor.Value = (decimal)Properties.Settings.Default["scaleFactor"]; - flatInbetween.Checked = (bool)Properties.Settings.Default["flatInbetween"]; fbxVersion.SelectedIndex = (int)Properties.Settings.Default["fbxVersion"]; fbxFormat.SelectedIndex = (int)Properties.Settings.Default["fbxFormat"]; } @@ -63,7 +62,6 @@ namespace AssetStudioGUI Properties.Settings.Default["skins"] = skins.Checked; Properties.Settings.Default["boneSize"] = boneSize.Value; Properties.Settings.Default["scaleFactor"] = scaleFactor.Value; - Properties.Settings.Default["flatInbetween"] = flatInbetween.Checked; Properties.Settings.Default["fbxVersion"] = fbxVersion.SelectedIndex; Properties.Settings.Default["fbxFormat"] = fbxFormat.SelectedIndex; Properties.Settings.Default.Save(); diff --git a/AssetStudioGUI/Exporter.cs b/AssetStudioGUI/Exporter.cs index 7a5fd53..28a246f 100644 --- a/AssetStudioGUI/Exporter.cs +++ b/AssetStudioGUI/Exporter.cs @@ -318,10 +318,9 @@ namespace AssetStudioGUI var skins = (bool)Properties.Settings.Default["skins"]; var boneSize = (int)(decimal)Properties.Settings.Default["boneSize"]; var scaleFactor = (float)(decimal)Properties.Settings.Default["scaleFactor"]; - var flatInbetween = (bool)Properties.Settings.Default["flatInbetween"]; var fbxVersion = (int)Properties.Settings.Default["fbxVersion"]; var fbxFormat = (int)Properties.Settings.Default["fbxFormat"]; - ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, flatInbetween, fbxVersion, fbxFormat == 1); + ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, fbxVersion, fbxFormat == 1); return true; } } diff --git a/AssetStudioGUI/Properties/Settings.Designer.cs b/AssetStudioGUI/Properties/Settings.Designer.cs index 4003fa0..a02cf19 100644 --- a/AssetStudioGUI/Properties/Settings.Designer.cs +++ b/AssetStudioGUI/Properties/Settings.Designer.cs @@ -203,18 +203,6 @@ namespace AssetStudioGUI.Properties { } } - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool flatInbetween { - get { - return ((bool)(this["flatInbetween"])); - } - set { - this["flatInbetween"] = value; - } - } - [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("3")] diff --git a/AssetStudioGUI/Properties/Settings.settings b/AssetStudioGUI/Properties/Settings.settings index e7958e3..a32ed14 100644 --- a/AssetStudioGUI/Properties/Settings.settings +++ b/AssetStudioGUI/Properties/Settings.settings @@ -47,9 +47,6 @@ 10 - - False - 3 diff --git a/AssetStudioGUI/app.config b/AssetStudioGUI/app.config index 02ad31c..245f5b0 100644 --- a/AssetStudioGUI/app.config +++ b/AssetStudioGUI/app.config @@ -52,9 +52,6 @@ 10 - - False - 3 diff --git a/AssetStudioUtility/ModelConverter.cs b/AssetStudioUtility/ModelConverter.cs index 42ce032..48ad2fa 100644 --- a/AssetStudioUtility/ModelConverter.cs +++ b/AssetStudioUtility/ModelConverter.cs @@ -403,55 +403,50 @@ namespace AssetStudio } //Morphs - if (mesh.m_Shapes?.shapes != null) + if (mesh.m_Shapes?.channels?.Length > 0) { - if (mesh.m_Shapes.shapes.Length > 0) + var morph = new ImportedMorph(); + MorphList.Add(morph); + morph.Path = iMesh.Path; + morph.Channels = new List(mesh.m_Shapes.channels.Length); + for (int i = 0; i < mesh.m_Shapes.channels.Length; i++) { - ImportedMorph morph = null; - string lastGroup = ""; - for (int i = 0; i < mesh.m_Shapes.channels.Length; i++) + var channel = new ImportedMorphChannel(); + morph.Channels.Add(channel); + var shapeChannel = mesh.m_Shapes.channels[i]; + channel.Name = shapeChannel.name; + channel.KeyframeList = new List(shapeChannel.frameCount); + var frameEnd = shapeChannel.frameIndex + shapeChannel.frameCount; + for (int frameIdx = shapeChannel.frameIndex; frameIdx < frameEnd; frameIdx++) { - string group = BlendShapeNameGroup(mesh, i); - if (group != lastGroup) + var keyframe = new ImportedMorphKeyframe(); + channel.KeyframeList.Add(keyframe); + keyframe.Weight = mesh.m_Shapes.fullWeights[frameIdx]; + var shape = mesh.m_Shapes.shapes[frameIdx]; + keyframe.hasNormals = shape.hasNormals; + keyframe.hasTangents = shape.hasTangents; + keyframe.VertexList = new List((int)shape.vertexCount); + var vertexEnd = shape.firstVertex + shape.vertexCount; + for (uint j = shape.firstVertex; j < vertexEnd; j++) { - morph = new ImportedMorph(); - MorphList.Add(morph); - morph.Path = iMesh.Path; - morph.ClipName = group; - morph.Channels = new List>(mesh.m_Shapes.channels.Length); - morph.KeyframeList = new List(mesh.m_Shapes.shapes.Length); - lastGroup = group; - } - - morph.Channels.Add(new Tuple(i < sMesh.m_BlendShapeWeights.Length ? sMesh.m_BlendShapeWeights[i] : 0f, morph.KeyframeList.Count, mesh.m_Shapes.channels[i].frameCount)); - for (int frameIdx = 0; frameIdx < mesh.m_Shapes.channels[i].frameCount; frameIdx++) - { - ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe(); - keyframe.Name = BlendShapeNameExtension(mesh, i) + "_" + frameIdx; - int shapeIdx = mesh.m_Shapes.channels[i].frameIndex + frameIdx; - keyframe.VertexList = new List((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount); - keyframe.MorphedVertexIndices = new List((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount); - keyframe.Weight = shapeIdx < mesh.m_Shapes.fullWeights.Length ? mesh.m_Shapes.fullWeights[shapeIdx] : 100f; - int lastVertIndex = (int)(mesh.m_Shapes.shapes[shapeIdx].firstVertex + mesh.m_Shapes.shapes[shapeIdx].vertexCount); - for (int j = (int)mesh.m_Shapes.shapes[shapeIdx].firstVertex; j < lastVertIndex; j++) + var destVertex = new ImportedMorphVertex(); + keyframe.VertexList.Add(destVertex); + var morphVertex = mesh.m_Shapes.vertices[j]; + destVertex.Index = morphVertex.index; + var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index); + destVertex.Vertex = new ImportedVertex(); + var morphPos = morphVertex.vertex; + destVertex.Vertex.Position = sourceVertex.Position + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z); + if (shape.hasNormals) { - var morphVert = mesh.m_Shapes.vertices[j]; - ImportedVertex vert = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index); - ImportedVertex destVert = new ImportedVertex(); - Vector3 morphPos = morphVert.vertex; - morphPos.X *= -1; - destVert.Position = vert.Position + morphPos; - Vector3 morphNormal = morphVert.normal; - morphNormal.X *= -1; - destVert.Normal = morphNormal; - Vector4 morphTangent = new Vector4(morphVert.tangent, 0); - morphTangent.X *= -1; - destVert.Tangent = morphTangent; - keyframe.VertexList.Add(destVert); - keyframe.MorphedVertexIndices.Add((ushort)morphVert.index); + var morphNormal = morphVertex.normal; + destVertex.Vertex.Normal = new Vector3(-morphNormal.X, morphNormal.Y, morphNormal.Z); + } + if (shape.hasTangents) + { + var morphTangent = morphVertex.tangent; + destVertex.Vertex.Tangent = new Vector4(-morphTangent.X, morphTangent.Y, morphTangent.Z, 0); } - - morph.KeyframeList.Add(keyframe); } } } diff --git a/AssetStudioUtility/ModelExporter.cs b/AssetStudioUtility/ModelExporter.cs index 6c81a06..41b8e17 100644 --- a/AssetStudioUtility/ModelExporter.cs +++ b/AssetStudioUtility/ModelExporter.cs @@ -2,9 +2,9 @@ { public static class ModelExporter { - public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii) + public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii) { - Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, flatInbetween, versionIndex, isAscii); + Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allFrames, allBones, skins, boneSize, scaleFactor, versionIndex, isAscii); } } }