mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-27 22:00:23 -04:00
improved morph export
This commit is contained in:
parent
eb4981808b
commit
a6264b39d1
@ -246,18 +246,27 @@ namespace AssetStudio
|
|||||||
public class ImportedMorph
|
public class ImportedMorph
|
||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public string ClipName { get; set; }
|
public List<ImportedMorphChannel> Channels { get; set; }
|
||||||
public List<Tuple<float, int, int>> Channels { get; set; }
|
}
|
||||||
|
|
||||||
|
public class ImportedMorphChannel
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
public List<ImportedMorphKeyframe> KeyframeList { get; set; }
|
public List<ImportedMorphKeyframe> KeyframeList { get; set; }
|
||||||
public List<ushort> MorphedVertexIndices { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportedMorphKeyframe
|
public class ImportedMorphKeyframe
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public bool hasNormals { get; set; }
|
||||||
public List<ImportedVertex> VertexList { get; set; }
|
public bool hasTangents { get; set; }
|
||||||
public List<ushort> MorphedVertexIndices { get; set; }
|
|
||||||
public float Weight { 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
|
public static class ImportedHelpers
|
||||||
|
@ -48,7 +48,7 @@ namespace AssetStudio {
|
|||||||
ref class Exporter
|
ref class Exporter
|
||||||
{
|
{
|
||||||
public:
|
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:
|
private:
|
||||||
bool exportSkins;
|
bool exportSkins;
|
||||||
@ -77,9 +77,9 @@ namespace AssetStudio {
|
|||||||
void ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame);
|
void ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame);
|
||||||
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList);
|
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList);
|
||||||
FbxFileTexture* ExportTexture(ImportedTexture^ matTex);
|
FbxFileTexture* ExportTexture(ImportedTexture^ matTex);
|
||||||
void ExportAnimations(bool eulerFilter, float filterValue, bool flatInbetween);
|
void ExportAnimations(bool eulerFilter, float filterValue);
|
||||||
void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision, bool flatInbetween);
|
void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision);
|
||||||
void ExportMorphs(bool morphMask, bool flatInbetween);
|
void ExportMorphs();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace AssetStudio
|
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);
|
FileInfo^ file = gcnew FileInfo(path);
|
||||||
DirectoryInfo^ dir = file->Directory;
|
DirectoryInfo^ dir = file->Directory;
|
||||||
@ -14,8 +14,8 @@ namespace AssetStudio
|
|||||||
Directory::SetCurrentDirectory(dir->FullName);
|
Directory::SetCurrentDirectory(dir->FullName);
|
||||||
auto name = Path::GetFileName(path);
|
auto name = Path::GetFileName(path);
|
||||||
Exporter^ exporter = gcnew Exporter(name, imported, allFrames, allBones, skins, boneSize, scaleFactor, versionIndex, isAscii);
|
Exporter^ exporter = gcnew Exporter(name, imported, allFrames, allBones, skins, boneSize, scaleFactor, versionIndex, isAscii);
|
||||||
//TODO exporter->ExportMorphs(false, flatInbetween);
|
exporter->ExportMorphs();
|
||||||
exporter->ExportAnimations(eulerFilter, filterPrecision, flatInbetween);
|
exporter->ExportAnimations(eulerFilter, filterPrecision);
|
||||||
exporter->pExporter->Export(exporter->pScene);
|
exporter->pExporter->Export(exporter->pScene);
|
||||||
delete exporter;
|
delete exporter;
|
||||||
|
|
||||||
@ -629,7 +629,7 @@ namespace AssetStudio
|
|||||||
prop.ConnectSrcObject(pTexture);
|
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;
|
auto importedAnimationList = imported->AnimationList;
|
||||||
if (importedAnimationList == nullptr)
|
if (importedAnimationList == nullptr)
|
||||||
@ -656,11 +656,11 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
kTakeName = FbxString("Take") + FbxString(i);
|
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;
|
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;
|
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)
|
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;
|
FbxBlendShape* lBlendShape = FbxBlendShape::Create(pScene, pNode->GetName());
|
||||||
for (int meshObjIdx = pBaseNode->GetChildCount() - meshList->SubmeshList->Count; meshObjIdx < meshList->SubmeshList->Count; meshObjIdx++)
|
pMesh->AddDeformer(lBlendShape);
|
||||||
{
|
|
||||||
List<ImportedVertex^>^ vertList = meshList->SubmeshList[meshObjIdx]->VertexList;
|
|
||||||
FbxNode* pBaseMeshNode = pBaseNode->GetChild(meshObjIdx);
|
|
||||||
FbxMesh* pBaseMesh = pBaseMeshNode->GetMesh();
|
|
||||||
int numColourSets = pBaseMesh->GetElementVertexColorCount();
|
|
||||||
|
|
||||||
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++)
|
for (int i = 0; i < morph->Channels->Count; i++)
|
||||||
{
|
{
|
||||||
|
auto channel = morph->Channels[i];
|
||||||
|
|
||||||
FbxBlendShapeChannel* lBlendShapeChannel;
|
FbxBlendShapeChannel* lBlendShapeChannel;
|
||||||
if (!flatInbetween)
|
|
||||||
{
|
|
||||||
WITH_MARSHALLED_STRING
|
WITH_MARSHALLED_STRING
|
||||||
(
|
(
|
||||||
pChannelName,
|
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 = 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);
|
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel);
|
||||||
|
|
||||||
WITH_MARSHALLED_STRING
|
for each(ImportedMorphKeyframe^ keyframe in channel->KeyframeList)
|
||||||
(
|
{
|
||||||
pMorphShapeName,
|
FbxShape* lShape = FbxShape::Create(pScene, "");
|
||||||
morph->ClipName + (meshList->SubmeshList->Count > 1 ? "_" + meshObjIdx : String::Empty) + "." + keyframe->Name,
|
lBlendShapeChannel->AddTargetShape(lShape, keyframe->Weight);
|
||||||
pShape = FbxShape::Create(pScene, pMorphShapeName);
|
|
||||||
);
|
|
||||||
lBlendShapeChannel->AddTargetShape(pShape, 100);
|
|
||||||
|
|
||||||
FbxProperty weightProp;
|
auto vectorCount = pMesh->GetControlPointsCount();
|
||||||
WITH_MARSHALLED_STRING
|
FbxVector4* orilVector4 = pMesh->GetControlPoints();
|
||||||
(
|
lShape->InitControlPoints(vectorCount);
|
||||||
pWeightName,
|
FbxVector4* lVector4 = lShape->GetControlPoints();
|
||||||
gcnew String(pShape->GetName()) + ".Weight",
|
|
||||||
weightProp = FbxProperty::Create(pBaseMesh, FbxDoubleDT, pWeightName);
|
|
||||||
);
|
|
||||||
weightProp.ModifyFlag(FbxPropertyFlags::eUserDefined, true);
|
|
||||||
weightProp.Set<double>(keyframe->Weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
pShape->InitControlPoints(vertList->Count);
|
for (int j = 0; j < vectorCount; j++)
|
||||||
FbxVector4* pControlPoints = pShape->GetControlPoints();
|
|
||||||
|
|
||||||
for (int j = 0; j < vertList->Count; j++)
|
|
||||||
{
|
{
|
||||||
ImportedVertex^ vertex = vertList[j];
|
auto vertex = orilVector4[j];
|
||||||
Vector3 coords = vertex->Position;
|
lVector4[j] = FbxVector4(vertex);
|
||||||
pControlPoints[j] = FbxVector4(coords.X, coords.Y, coords.Z, 0);
|
|
||||||
}
|
}
|
||||||
List<unsigned short>^ meshIndices = keyframe->MorphedVertexIndices;
|
for (int j = 0; j < keyframe->VertexList->Count; j++)
|
||||||
for (int j = 0; j < meshIndices->Count; j++)
|
|
||||||
{
|
{
|
||||||
int controlPointIndex = meshIndices[j] - meshVertexIndex;
|
auto index = keyframe->VertexList[j]->Index;
|
||||||
if (controlPointIndex >= 0 && controlPointIndex < vertList->Count)
|
auto coords = keyframe->VertexList[j]->Vertex->Position;
|
||||||
{
|
lVector4[index] = FbxVector4(coords.X, coords.Y, coords.Z, 0);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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.label4 = new System.Windows.Forms.Label();
|
||||||
this.fbxVersion = new System.Windows.Forms.ComboBox();
|
this.fbxVersion = new System.Windows.Forms.ComboBox();
|
||||||
this.label3 = new System.Windows.Forms.Label();
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
this.flatInbetween = new System.Windows.Forms.CheckBox();
|
|
||||||
this.boneSize = new System.Windows.Forms.NumericUpDown();
|
this.boneSize = new System.Windows.Forms.NumericUpDown();
|
||||||
this.label2 = new System.Windows.Forms.Label();
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
this.skins = new System.Windows.Forms.CheckBox();
|
this.skins = new System.Windows.Forms.CheckBox();
|
||||||
@ -63,7 +62,7 @@
|
|||||||
//
|
//
|
||||||
// OKbutton
|
// 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.Name = "OKbutton";
|
||||||
this.OKbutton.Size = new System.Drawing.Size(75, 21);
|
this.OKbutton.Size = new System.Drawing.Size(75, 21);
|
||||||
this.OKbutton.TabIndex = 6;
|
this.OKbutton.TabIndex = 6;
|
||||||
@ -74,7 +73,7 @@
|
|||||||
// Cancel
|
// Cancel
|
||||||
//
|
//
|
||||||
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.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.Name = "Cancel";
|
||||||
this.Cancel.Size = new System.Drawing.Size(75, 21);
|
this.Cancel.Size = new System.Drawing.Size(75, 21);
|
||||||
this.Cancel.TabIndex = 7;
|
this.Cancel.TabIndex = 7;
|
||||||
@ -170,7 +169,6 @@
|
|||||||
this.groupBox2.Controls.Add(this.label4);
|
this.groupBox2.Controls.Add(this.label4);
|
||||||
this.groupBox2.Controls.Add(this.fbxVersion);
|
this.groupBox2.Controls.Add(this.fbxVersion);
|
||||||
this.groupBox2.Controls.Add(this.label3);
|
this.groupBox2.Controls.Add(this.label3);
|
||||||
this.groupBox2.Controls.Add(this.flatInbetween);
|
|
||||||
this.groupBox2.Controls.Add(this.boneSize);
|
this.groupBox2.Controls.Add(this.boneSize);
|
||||||
this.groupBox2.Controls.Add(this.label2);
|
this.groupBox2.Controls.Add(this.label2);
|
||||||
this.groupBox2.Controls.Add(this.skins);
|
this.groupBox2.Controls.Add(this.skins);
|
||||||
@ -181,7 +179,7 @@
|
|||||||
this.groupBox2.Controls.Add(this.eulerFilter);
|
this.groupBox2.Controls.Add(this.eulerFilter);
|
||||||
this.groupBox2.Location = new System.Drawing.Point(12, 12);
|
this.groupBox2.Location = new System.Drawing.Point(12, 12);
|
||||||
this.groupBox2.Name = "groupBox2";
|
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.TabIndex = 11;
|
||||||
this.groupBox2.TabStop = false;
|
this.groupBox2.TabStop = false;
|
||||||
this.groupBox2.Text = "Fbx";
|
this.groupBox2.Text = "Fbx";
|
||||||
@ -221,7 +219,7 @@
|
|||||||
this.fbxFormat.Items.AddRange(new object[] {
|
this.fbxFormat.Items.AddRange(new object[] {
|
||||||
"Binary",
|
"Binary",
|
||||||
"Ascii"});
|
"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.Name = "fbxFormat";
|
||||||
this.fbxFormat.Size = new System.Drawing.Size(61, 20);
|
this.fbxFormat.Size = new System.Drawing.Size(61, 20);
|
||||||
this.fbxFormat.TabIndex = 18;
|
this.fbxFormat.TabIndex = 18;
|
||||||
@ -229,7 +227,7 @@
|
|||||||
// label4
|
// label4
|
||||||
//
|
//
|
||||||
this.label4.AutoSize = true;
|
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.Name = "label4";
|
||||||
this.label4.Size = new System.Drawing.Size(59, 12);
|
this.label4.Size = new System.Drawing.Size(59, 12);
|
||||||
this.label4.TabIndex = 17;
|
this.label4.TabIndex = 17;
|
||||||
@ -246,7 +244,7 @@
|
|||||||
"7.3",
|
"7.3",
|
||||||
"7.4",
|
"7.4",
|
||||||
"7.5"});
|
"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.Name = "fbxVersion";
|
||||||
this.fbxVersion.Size = new System.Drawing.Size(47, 20);
|
this.fbxVersion.Size = new System.Drawing.Size(47, 20);
|
||||||
this.fbxVersion.TabIndex = 16;
|
this.fbxVersion.TabIndex = 16;
|
||||||
@ -254,22 +252,12 @@
|
|||||||
// label3
|
// label3
|
||||||
//
|
//
|
||||||
this.label3.AutoSize = true;
|
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.Name = "label3";
|
||||||
this.label3.Size = new System.Drawing.Size(65, 12);
|
this.label3.Size = new System.Drawing.Size(65, 12);
|
||||||
this.label3.TabIndex = 15;
|
this.label3.TabIndex = 15;
|
||||||
this.label3.Text = "FBXVersion";
|
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
|
// boneSize
|
||||||
//
|
//
|
||||||
this.boneSize.Location = new System.Drawing.Point(65, 128);
|
this.boneSize.Location = new System.Drawing.Point(65, 128);
|
||||||
@ -345,6 +333,8 @@
|
|||||||
// allFrames
|
// allFrames
|
||||||
//
|
//
|
||||||
this.allFrames.AutoSize = true;
|
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.Location = new System.Drawing.Point(6, 61);
|
||||||
this.allFrames.Name = "allFrames";
|
this.allFrames.Name = "allFrames";
|
||||||
this.allFrames.Size = new System.Drawing.Size(78, 16);
|
this.allFrames.Size = new System.Drawing.Size(78, 16);
|
||||||
@ -370,7 +360,7 @@
|
|||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.CancelButton = this.Cancel;
|
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.groupBox2);
|
||||||
this.Controls.Add(this.groupBox1);
|
this.Controls.Add(this.groupBox1);
|
||||||
this.Controls.Add(this.Cancel);
|
this.Controls.Add(this.Cancel);
|
||||||
@ -408,7 +398,6 @@
|
|||||||
private System.Windows.Forms.CheckBox convertAudio;
|
private System.Windows.Forms.CheckBox convertAudio;
|
||||||
private System.Windows.Forms.Panel panel1;
|
private System.Windows.Forms.Panel panel1;
|
||||||
private System.Windows.Forms.GroupBox groupBox2;
|
private System.Windows.Forms.GroupBox groupBox2;
|
||||||
private System.Windows.Forms.CheckBox flatInbetween;
|
|
||||||
private System.Windows.Forms.NumericUpDown boneSize;
|
private System.Windows.Forms.NumericUpDown boneSize;
|
||||||
private System.Windows.Forms.Label label2;
|
private System.Windows.Forms.Label label2;
|
||||||
private System.Windows.Forms.CheckBox skins;
|
private System.Windows.Forms.CheckBox skins;
|
||||||
|
@ -33,7 +33,6 @@ namespace AssetStudioGUI
|
|||||||
skins.Checked = (bool)Properties.Settings.Default["skins"];
|
skins.Checked = (bool)Properties.Settings.Default["skins"];
|
||||||
boneSize.Value = (decimal)Properties.Settings.Default["boneSize"];
|
boneSize.Value = (decimal)Properties.Settings.Default["boneSize"];
|
||||||
scaleFactor.Value = (decimal)Properties.Settings.Default["scaleFactor"];
|
scaleFactor.Value = (decimal)Properties.Settings.Default["scaleFactor"];
|
||||||
flatInbetween.Checked = (bool)Properties.Settings.Default["flatInbetween"];
|
|
||||||
fbxVersion.SelectedIndex = (int)Properties.Settings.Default["fbxVersion"];
|
fbxVersion.SelectedIndex = (int)Properties.Settings.Default["fbxVersion"];
|
||||||
fbxFormat.SelectedIndex = (int)Properties.Settings.Default["fbxFormat"];
|
fbxFormat.SelectedIndex = (int)Properties.Settings.Default["fbxFormat"];
|
||||||
}
|
}
|
||||||
@ -63,7 +62,6 @@ namespace AssetStudioGUI
|
|||||||
Properties.Settings.Default["skins"] = skins.Checked;
|
Properties.Settings.Default["skins"] = skins.Checked;
|
||||||
Properties.Settings.Default["boneSize"] = boneSize.Value;
|
Properties.Settings.Default["boneSize"] = boneSize.Value;
|
||||||
Properties.Settings.Default["scaleFactor"] = scaleFactor.Value;
|
Properties.Settings.Default["scaleFactor"] = scaleFactor.Value;
|
||||||
Properties.Settings.Default["flatInbetween"] = flatInbetween.Checked;
|
|
||||||
Properties.Settings.Default["fbxVersion"] = fbxVersion.SelectedIndex;
|
Properties.Settings.Default["fbxVersion"] = fbxVersion.SelectedIndex;
|
||||||
Properties.Settings.Default["fbxFormat"] = fbxFormat.SelectedIndex;
|
Properties.Settings.Default["fbxFormat"] = fbxFormat.SelectedIndex;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
|
@ -318,10 +318,9 @@ namespace AssetStudioGUI
|
|||||||
var skins = (bool)Properties.Settings.Default["skins"];
|
var skins = (bool)Properties.Settings.Default["skins"];
|
||||||
var boneSize = (int)(decimal)Properties.Settings.Default["boneSize"];
|
var boneSize = (int)(decimal)Properties.Settings.Default["boneSize"];
|
||||||
var scaleFactor = (float)(decimal)Properties.Settings.Default["scaleFactor"];
|
var scaleFactor = (float)(decimal)Properties.Settings.Default["scaleFactor"];
|
||||||
var flatInbetween = (bool)Properties.Settings.Default["flatInbetween"];
|
|
||||||
var fbxVersion = (int)Properties.Settings.Default["fbxVersion"];
|
var fbxVersion = (int)Properties.Settings.Default["fbxVersion"];
|
||||||
var fbxFormat = (int)Properties.Settings.Default["fbxFormat"];
|
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;
|
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.Configuration.UserScopedSettingAttribute()]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("3")]
|
[global::System.Configuration.DefaultSettingValueAttribute("3")]
|
||||||
|
@ -47,9 +47,6 @@
|
|||||||
<Setting Name="boneSize" Type="System.Decimal" Scope="User">
|
<Setting Name="boneSize" Type="System.Decimal" Scope="User">
|
||||||
<Value Profile="(Default)">10</Value>
|
<Value Profile="(Default)">10</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
<Setting Name="flatInbetween" Type="System.Boolean" Scope="User">
|
|
||||||
<Value Profile="(Default)">False</Value>
|
|
||||||
</Setting>
|
|
||||||
<Setting Name="fbxVersion" Type="System.Int32" Scope="User">
|
<Setting Name="fbxVersion" Type="System.Int32" Scope="User">
|
||||||
<Value Profile="(Default)">3</Value>
|
<Value Profile="(Default)">3</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
@ -52,9 +52,6 @@
|
|||||||
<setting name="boneSize" serializeAs="String">
|
<setting name="boneSize" serializeAs="String">
|
||||||
<value>10</value>
|
<value>10</value>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="flatInbetween" serializeAs="String">
|
|
||||||
<value>False</value>
|
|
||||||
</setting>
|
|
||||||
<setting name="fbxVersion" serializeAs="String">
|
<setting name="fbxVersion" serializeAs="String">
|
||||||
<value>3</value>
|
<value>3</value>
|
||||||
</setting>
|
</setting>
|
||||||
|
@ -403,55 +403,50 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Morphs
|
//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();
|
||||||
{
|
|
||||||
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();
|
|
||||||
MorphList.Add(morph);
|
MorphList.Add(morph);
|
||||||
morph.Path = iMesh.Path;
|
morph.Path = iMesh.Path;
|
||||||
morph.ClipName = group;
|
morph.Channels = new List<ImportedMorphChannel>(mesh.m_Shapes.channels.Length);
|
||||||
morph.Channels = new List<Tuple<float, int, int>>(mesh.m_Shapes.channels.Length);
|
for (int i = 0; i < mesh.m_Shapes.channels.Length; i++)
|
||||||
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++)
|
|
||||||
{
|
{
|
||||||
ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe();
|
var channel = new ImportedMorphChannel();
|
||||||
keyframe.Name = BlendShapeNameExtension(mesh, i) + "_" + frameIdx;
|
morph.Channels.Add(channel);
|
||||||
int shapeIdx = mesh.m_Shapes.channels[i].frameIndex + frameIdx;
|
var shapeChannel = mesh.m_Shapes.channels[i];
|
||||||
keyframe.VertexList = new List<ImportedVertex>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount);
|
channel.Name = shapeChannel.name;
|
||||||
keyframe.MorphedVertexIndices = new List<ushort>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount);
|
channel.KeyframeList = new List<ImportedMorphKeyframe>(shapeChannel.frameCount);
|
||||||
keyframe.Weight = shapeIdx < mesh.m_Shapes.fullWeights.Length ? mesh.m_Shapes.fullWeights[shapeIdx] : 100f;
|
var frameEnd = shapeChannel.frameIndex + shapeChannel.frameCount;
|
||||||
int lastVertIndex = (int)(mesh.m_Shapes.shapes[shapeIdx].firstVertex + mesh.m_Shapes.shapes[shapeIdx].vertexCount);
|
for (int frameIdx = shapeChannel.frameIndex; frameIdx < frameEnd; frameIdx++)
|
||||||
for (int j = (int)mesh.m_Shapes.shapes[shapeIdx].firstVertex; j < lastVertIndex; j++)
|
|
||||||
{
|
{
|
||||||
var morphVert = mesh.m_Shapes.vertices[j];
|
var keyframe = new ImportedMorphKeyframe();
|
||||||
ImportedVertex vert = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index);
|
channel.KeyframeList.Add(keyframe);
|
||||||
ImportedVertex destVert = new ImportedVertex();
|
keyframe.Weight = mesh.m_Shapes.fullWeights[frameIdx];
|
||||||
Vector3 morphPos = morphVert.vertex;
|
var shape = mesh.m_Shapes.shapes[frameIdx];
|
||||||
morphPos.X *= -1;
|
keyframe.hasNormals = shape.hasNormals;
|
||||||
destVert.Position = vert.Position + morphPos;
|
keyframe.hasTangents = shape.hasTangents;
|
||||||
Vector3 morphNormal = morphVert.normal;
|
keyframe.VertexList = new List<ImportedMorphVertex>((int)shape.vertexCount);
|
||||||
morphNormal.X *= -1;
|
var vertexEnd = shape.firstVertex + shape.vertexCount;
|
||||||
destVert.Normal = morphNormal;
|
for (uint j = shape.firstVertex; j < vertexEnd; j++)
|
||||||
Vector4 morphTangent = new Vector4(morphVert.tangent, 0);
|
{
|
||||||
morphTangent.X *= -1;
|
var destVertex = new ImportedMorphVertex();
|
||||||
destVert.Tangent = morphTangent;
|
keyframe.VertexList.Add(destVertex);
|
||||||
keyframe.VertexList.Add(destVert);
|
var morphVertex = mesh.m_Shapes.vertices[j];
|
||||||
keyframe.MorphedVertexIndices.Add((ushort)morphVert.index);
|
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 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