mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-25 05:40:21 -04:00
improved morph export
This commit is contained in:
parent
eb4981808b
commit
a6264b39d1
@ -246,18 +246,27 @@ namespace AssetStudio
|
||||
public class ImportedMorph
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public string ClipName { get; set; }
|
||||
public List<Tuple<float, int, int>> Channels { get; set; }
|
||||
public List<ImportedMorphChannel> Channels { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedMorphChannel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<ImportedMorphKeyframe> KeyframeList { get; set; }
|
||||
public List<ushort> MorphedVertexIndices { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedMorphKeyframe
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<ImportedVertex> VertexList { get; set; }
|
||||
public List<ushort> MorphedVertexIndices { get; set; }
|
||||
public bool hasNormals { get; set; }
|
||||
public bool hasTangents { get; set; }
|
||||
public float Weight { get; set; }
|
||||
public List<ImportedMorphVertex> VertexList { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedMorphVertex
|
||||
{
|
||||
public uint Index { get; set; }
|
||||
public ImportedVertex Vertex { get; set; }
|
||||
}
|
||||
|
||||
public static class ImportedHelpers
|
||||
|
@ -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();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -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<ImportedAnimationKeyframedTrack^>^ 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++)
|
||||
{
|
||||
ImportedMesh^ meshList = imported->MeshList[meshIdx];
|
||||
FbxNode* pBaseNode = NULL;
|
||||
for (int nodeIdx = 0; nodeIdx < pMeshNodes->GetCount(); nodeIdx++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
for each (ImportedMorph^ morph in imported->MorphList)
|
||||
{
|
||||
if (morph->Path != meshList->Path)
|
||||
auto frame = imported->RootFrame->FindFrameByPath(morph->Path);
|
||||
if (frame != nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
FbxNode* pNode = (FbxNode*)frameToNode[frame];
|
||||
FbxMesh* pMesh = pNode->GetMesh();
|
||||
|
||||
int meshVertexIndex = 0;
|
||||
for (int meshObjIdx = pBaseNode->GetChildCount() - meshList->SubmeshList->Count; meshObjIdx < meshList->SubmeshList->Count; meshObjIdx++)
|
||||
{
|
||||
List<ImportedVertex^>^ vertList = meshList->SubmeshList[meshObjIdx]->VertexList;
|
||||
FbxNode* pBaseMeshNode = pBaseNode->GetChild(meshObjIdx);
|
||||
FbxMesh* pBaseMesh = pBaseMeshNode->GetMesh();
|
||||
int numColourSets = pBaseMesh->GetElementVertexColorCount();
|
||||
FbxBlendShape* lBlendShape = FbxBlendShape::Create(pScene, pNode->GetName());
|
||||
pMesh->AddDeformer(lBlendShape);
|
||||
|
||||
FbxBlendShape* lBlendShape;
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pShapeName,
|
||||
morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty),
|
||||
lBlendShape = FbxBlendShape::Create(pScene, pShapeName);
|
||||
);
|
||||
FbxProperty rootGroupProp = FbxProperty::Create(lBlendShape, FbxStringDT, "RootGroup");
|
||||
pBaseMesh->AddDeformer(lBlendShape);
|
||||
List<ImportedMorphKeyframe^>^ keyframes = morph->KeyframeList;
|
||||
for (int i = 0; i < morph->Channels->Count; i++)
|
||||
{
|
||||
auto channel = morph->Channels[i];
|
||||
|
||||
FbxBlendShapeChannel* lBlendShapeChannel;
|
||||
if (!flatInbetween)
|
||||
{
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pChannelName,
|
||||
gcnew String(lBlendShape->GetName()) + "." + keyframes[morph->Channels[i]->Item2]->Name->Substring(0, keyframes[morph->Channels[i]->Item2]->Name->LastIndexOf("_")),
|
||||
channel->Name,
|
||||
lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, pChannelName);
|
||||
);
|
||||
lBlendShapeChannel->DeformPercent = morph->Channels[i]->Item1;
|
||||
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel);
|
||||
}
|
||||
|
||||
for (int frameIdx = 0; frameIdx < morph->Channels[i]->Item3; frameIdx++)
|
||||
{
|
||||
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<FbxShape>(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);
|
||||
for each(ImportedMorphKeyframe^ keyframe in channel->KeyframeList)
|
||||
{
|
||||
FbxShape* lShape = FbxShape::Create(pScene, "");
|
||||
lBlendShapeChannel->AddTargetShape(lShape, keyframe->Weight);
|
||||
|
||||
FbxProperty weightProp;
|
||||
WITH_MARSHALLED_STRING
|
||||
(
|
||||
pWeightName,
|
||||
gcnew String(pShape->GetName()) + ".Weight",
|
||||
weightProp = FbxProperty::Create(pBaseMesh, FbxDoubleDT, pWeightName);
|
||||
);
|
||||
weightProp.ModifyFlag(FbxPropertyFlags::eUserDefined, true);
|
||||
weightProp.Set<double>(keyframe->Weight);
|
||||
}
|
||||
auto vectorCount = pMesh->GetControlPointsCount();
|
||||
FbxVector4* orilVector4 = pMesh->GetControlPoints();
|
||||
lShape->InitControlPoints(vectorCount);
|
||||
FbxVector4* lVector4 = lShape->GetControlPoints();
|
||||
|
||||
pShape->InitControlPoints(vertList->Count);
|
||||
FbxVector4* pControlPoints = pShape->GetControlPoints();
|
||||
|
||||
for (int j = 0; j < vertList->Count; j++)
|
||||
for (int j = 0; j < vectorCount; j++)
|
||||
{
|
||||
ImportedVertex^ vertex = vertList[j];
|
||||
Vector3 coords = vertex->Position;
|
||||
pControlPoints[j] = FbxVector4(coords.X, coords.Y, coords.Z, 0);
|
||||
auto vertex = orilVector4[j];
|
||||
lVector4[j] = FbxVector4(vertex);
|
||||
}
|
||||
List<unsigned short>^ meshIndices = keyframe->MorphedVertexIndices;
|
||||
for (int j = 0; j < meshIndices->Count; j++)
|
||||
for (int j = 0; j < keyframe->VertexList->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<unsigned short>^ 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;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
31
AssetStudioGUI/ExportOptions.Designer.cs
generated
31
AssetStudioGUI/ExportOptions.Designer.cs
generated
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
12
AssetStudioGUI/Properties/Settings.Designer.cs
generated
12
AssetStudioGUI/Properties/Settings.Designer.cs
generated
@ -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")]
|
||||
|
@ -47,9 +47,6 @@
|
||||
<Setting Name="boneSize" Type="System.Decimal" Scope="User">
|
||||
<Value Profile="(Default)">10</Value>
|
||||
</Setting>
|
||||
<Setting Name="flatInbetween" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="fbxVersion" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">3</Value>
|
||||
</Setting>
|
||||
|
@ -52,9 +52,6 @@
|
||||
<setting name="boneSize" serializeAs="String">
|
||||
<value>10</value>
|
||||
</setting>
|
||||
<setting name="flatInbetween" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="fbxVersion" serializeAs="String">
|
||||
<value>3</value>
|
||||
</setting>
|
||||
|
@ -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)
|
||||
{
|
||||
ImportedMorph morph = null;
|
||||
string lastGroup = "";
|
||||
for (int i = 0; i < mesh.m_Shapes.channels.Length; i++)
|
||||
{
|
||||
string group = BlendShapeNameGroup(mesh, i);
|
||||
if (group != lastGroup)
|
||||
{
|
||||
morph = new ImportedMorph();
|
||||
var morph = new ImportedMorph();
|
||||
MorphList.Add(morph);
|
||||
morph.Path = iMesh.Path;
|
||||
morph.ClipName = group;
|
||||
morph.Channels = new List<Tuple<float, int, int>>(mesh.m_Shapes.channels.Length);
|
||||
morph.KeyframeList = new List<ImportedMorphKeyframe>(mesh.m_Shapes.shapes.Length);
|
||||
lastGroup = group;
|
||||
}
|
||||
|
||||
morph.Channels.Add(new Tuple<float, int, int>(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++)
|
||||
morph.Channels = new List<ImportedMorphChannel>(mesh.m_Shapes.channels.Length);
|
||||
for (int i = 0; i < mesh.m_Shapes.channels.Length; i++)
|
||||
{
|
||||
ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe();
|
||||
keyframe.Name = BlendShapeNameExtension(mesh, i) + "_" + frameIdx;
|
||||
int shapeIdx = mesh.m_Shapes.channels[i].frameIndex + frameIdx;
|
||||
keyframe.VertexList = new List<ImportedVertex>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount);
|
||||
keyframe.MorphedVertexIndices = new List<ushort>((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 channel = new ImportedMorphChannel();
|
||||
morph.Channels.Add(channel);
|
||||
var shapeChannel = mesh.m_Shapes.channels[i];
|
||||
channel.Name = shapeChannel.name;
|
||||
channel.KeyframeList = new List<ImportedMorphKeyframe>(shapeChannel.frameCount);
|
||||
var frameEnd = shapeChannel.frameIndex + shapeChannel.frameCount;
|
||||
for (int frameIdx = shapeChannel.frameIndex; frameIdx < frameEnd; frameIdx++)
|
||||
{
|
||||
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 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<ImportedMorphVertex>((int)shape.vertexCount);
|
||||
var vertexEnd = shape.firstVertex + shape.vertexCount;
|
||||
for (uint j = shape.firstVertex; j < vertexEnd; 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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user