mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43:25 +00:00
Fix models export. Improve export coordinate system selection.
This commit is contained in:
parent
13c12f9bd3
commit
4fecc76b59
4 changed files with 68 additions and 84 deletions
|
|
@ -211,6 +211,56 @@ bool LoadScene(FbxManager* pManager, FbxDocument* pScene, const char* pFilename)
|
||||||
return lStatus;
|
return lStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://twitter.com/FreyaHolmer/status/644881436982575104
|
||||||
|
// https://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_axis_system_html
|
||||||
|
cl::opt<FbxAxisSystem::EPreDefinedAxisSystem> AS(cl::desc("Choose axis system (fbx only):"),
|
||||||
|
cl::values(
|
||||||
|
#define axisval(x, y) \
|
||||||
|
cl::OptionEnumValue{ #x, FbxAxisSystem::EPreDefinedAxisSystem::x, y }
|
||||||
|
|
||||||
|
axisval(eMayaZUp, "UpVector = ZAxis, FrontVector = -ParityOdd, CoordSystem = RightHanded"),
|
||||||
|
axisval(eMayaYUp, "UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = RightHanded (default)"),
|
||||||
|
axisval(eMax, "UpVector = ZAxis, FrontVector = -ParityOdd, CoordSystem = RightHanded"),
|
||||||
|
cl::OptionEnumValue{"eBlender", FbxAxisSystem::EPreDefinedAxisSystem::eMax,
|
||||||
|
"UpVector = ZAxis, FrontVector = -ParityOdd, CoordSystem = RightHanded\n(when importing, disable 'Use Pre/Post Rotation')"},
|
||||||
|
axisval(eMotionBuilder, "UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = RightHanded"),
|
||||||
|
axisval(eOpenGL, "UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = RightHanded"),
|
||||||
|
axisval(eDirectX, "UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = LeftHanded"),
|
||||||
|
axisval(eLightwave, "UpVector = YAxis, FrontVector = ParityOdd, CoordSystem = LeftHanded")
|
||||||
|
|
||||||
|
#undef axisval
|
||||||
|
)
|
||||||
|
, cl::init(FbxAxisSystem::EPreDefinedAxisSystem::eMayaYUp)
|
||||||
|
);
|
||||||
|
|
||||||
|
void ConvertScene(FbxScene* lScene)
|
||||||
|
{
|
||||||
|
switch (AS.getValue())
|
||||||
|
{
|
||||||
|
case FbxAxisSystem::EPreDefinedAxisSystem::eMayaZUp:
|
||||||
|
FbxAxisSystem::MayaZUp.ConvertScene(lScene);
|
||||||
|
break;
|
||||||
|
case FbxAxisSystem::EPreDefinedAxisSystem::eMax:
|
||||||
|
FbxAxisSystem::Max.ConvertScene(lScene);
|
||||||
|
break;
|
||||||
|
case FbxAxisSystem::EPreDefinedAxisSystem::eMotionBuilder:
|
||||||
|
FbxAxisSystem::Motionbuilder.ConvertScene(lScene);
|
||||||
|
break;
|
||||||
|
case FbxAxisSystem::EPreDefinedAxisSystem::eOpenGL:
|
||||||
|
FbxAxisSystem::OpenGL.ConvertScene(lScene);
|
||||||
|
break;
|
||||||
|
case FbxAxisSystem::EPreDefinedAxisSystem::eDirectX:
|
||||||
|
FbxAxisSystem::DirectX.ConvertScene(lScene);
|
||||||
|
break;
|
||||||
|
case FbxAxisSystem::EPreDefinedAxisSystem::eLightwave:
|
||||||
|
FbxAxisSystem::Lightwave.ConvertScene(lScene);
|
||||||
|
break;
|
||||||
|
case FbxAxisSystem::EPreDefinedAxisSystem::eMayaYUp:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void model::printFbx(const std::string &fn) const
|
void model::printFbx(const std::string &fn) const
|
||||||
{
|
{
|
||||||
FbxManager* lSdkManager = NULL;
|
FbxManager* lSdkManager = NULL;
|
||||||
|
|
@ -219,12 +269,11 @@ void model::printFbx(const std::string &fn) const
|
||||||
// Prepare the FBX SDK.
|
// Prepare the FBX SDK.
|
||||||
InitializeSdkObjects(lSdkManager, lScene);
|
InitializeSdkObjects(lSdkManager, lScene);
|
||||||
|
|
||||||
// default is ???
|
|
||||||
//FbxAxisSystem::MayaZUp.ConvertScene(lScene);
|
|
||||||
|
|
||||||
// Create the scene.
|
// Create the scene.
|
||||||
CreateScene(*this, fn, lSdkManager, lScene);
|
CreateScene(*this, fn, lSdkManager, lScene);
|
||||||
|
|
||||||
|
ConvertScene(lScene);
|
||||||
|
|
||||||
SaveScene(lSdkManager, lScene, (fn + ".fbx").c_str());
|
SaveScene(lSdkManager, lScene, (fn + ".fbx").c_str());
|
||||||
//SaveScene(lSdkManager, lScene, (fn + "_ue4.fbx").c_str());
|
//SaveScene(lSdkManager, lScene, (fn + "_ue4.fbx").c_str());
|
||||||
//if (all_formats)
|
//if (all_formats)
|
||||||
|
|
@ -249,7 +298,7 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
||||||
return socket;
|
return socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto create_socket = [&create_socket_named](const auto &b, const std::string &name, bool mirror_x = false)
|
auto create_socket = [&create_socket_named](const auto &b, const std::string &name, bool mirror_y = false)
|
||||||
{
|
{
|
||||||
FbxVector4 c;
|
FbxVector4 c;
|
||||||
for (auto &v : b.vertices)
|
for (auto &v : b.vertices)
|
||||||
|
|
@ -261,12 +310,9 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
||||||
c /= b.vertices.size();
|
c /= b.vertices.size();
|
||||||
|
|
||||||
auto s = create_socket_named(name);
|
auto s = create_socket_named(name);
|
||||||
// here we must mirror 'first' number (original x)
|
if (mirror_y) // y is the second coord, idx = 1
|
||||||
// it depends on what order was during loading
|
c.mData[1] = -c.mData[1];
|
||||||
if (mirror_x)
|
|
||||||
c.mData[get_x_coordinate_id()] = -c.mData[get_x_coordinate_id()];
|
|
||||||
s->LclTranslation.Set(c);
|
s->LclTranslation.Set(c);
|
||||||
//s->LclScaling.Set(FbxDouble3(scale_mult(), scale_mult(), scale_mult()));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int engine_id = 0;
|
int engine_id = 0;
|
||||||
|
|
@ -339,9 +385,9 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
||||||
// add vertices, normals, uvs
|
// add vertices, normals, uvs
|
||||||
for (const auto &[i,v] : enumerate(b.vertices))
|
for (const auto &[i,v] : enumerate(b.vertices))
|
||||||
{
|
{
|
||||||
FbxVector4 x(v.coordinates.x * scale_mult(), v.coordinates.y * scale_mult(), v.coordinates.z * scale_mult(), v.coordinates.w);
|
FbxVector4 cp(v.coordinates.x * scale_mult(), v.coordinates.y * scale_mult(), v.coordinates.z * scale_mult(), v.coordinates.w);
|
||||||
FbxVector4 n(v.normal.x, v.normal.y, v.normal.z);
|
FbxVector4 n(v.normal.x, v.normal.y, v.normal.z);
|
||||||
m->SetControlPointAt(x, n, i);
|
m->SetControlPointAt(cp, n, i);
|
||||||
|
|
||||||
float f;
|
float f;
|
||||||
auto uc = modf(fabs(v.texture_coordinates.u), &f);
|
auto uc = modf(fabs(v.texture_coordinates.u), &f);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ bool silent = false;
|
||||||
bool printMaxPolygonBlock = false;
|
bool printMaxPolygonBlock = false;
|
||||||
|
|
||||||
cl::opt<path> p(cl::Positional, cl::desc("<MOD_ file or directory with MOD_ files>"), cl::value_desc("file or directory"), cl::Required);
|
cl::opt<path> p(cl::Positional, cl::desc("<MOD_ file or directory with MOD_ files>"), cl::value_desc("file or directory"), cl::Required);
|
||||||
cl::opt<bool> all_formats("af", cl::desc("All formats"));
|
cl::opt<bool> all_formats("af", cl::desc("All formats (.obj, .fbx)"));
|
||||||
|
|
||||||
yaml root;
|
yaml root;
|
||||||
cl::opt<bool> stats("i", cl::desc("Gather information from (models)"));
|
cl::opt<bool> stats("i", cl::desc("Gather information from (models)"));
|
||||||
|
|
|
||||||
|
|
@ -84,82 +84,21 @@ std::string translate(const std::string &s)
|
||||||
return s3;
|
return s3;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AxisSystem
|
|
||||||
{
|
|
||||||
MayaYUpZFrontRH,
|
|
||||||
Windows3dViewer = MayaYUpZFrontRH,
|
|
||||||
|
|
||||||
AIM,
|
|
||||||
UE4 = AIM, // Do not use 'Convert scene' during UE4 import!
|
|
||||||
|
|
||||||
ax_aim = AIM,
|
|
||||||
ax_ue4 = ax_aim,
|
|
||||||
ax_maya_y = MayaYUpZFrontRH,
|
|
||||||
ax_win_3d_viewer = ax_maya_y,
|
|
||||||
};
|
|
||||||
|
|
||||||
cl::opt<AxisSystem> AS(cl::desc("Choose axis system:"),
|
|
||||||
cl::values(
|
|
||||||
clEnumVal(ax_ue4, "Original AIM or UE4 axis system"),
|
|
||||||
clEnumVal(ax_maya_y, "Default MAYA Y-Up Z-Front or Windows 3d Viewer axis system")
|
|
||||||
)
|
|
||||||
, cl::init(AxisSystem::UE4)
|
|
||||||
);
|
|
||||||
|
|
||||||
int get_x_coordinate_id()
|
|
||||||
{
|
|
||||||
switch (AS)
|
|
||||||
{
|
|
||||||
case AxisSystem::AIM:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void load_translated(aim_vector3<float> &v, const buffer &b)
|
static void load_translated(aim_vector3<float> &v, const buffer &b)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Our coord system:
|
AIM Coordinates (.mod file coord system, 100% sure):
|
||||||
|
1st number: -Y (front, -ParityOdd)
|
||||||
^ z
|
2nd number: +X (right, thus RH)
|
||||||
|
|
3rd number: +Z (up)
|
||||||
---> y
|
This is Z UP, RH axis system - eMax (same as eMayaZUp) in fbx.
|
||||||
/
|
|
||||||
v x
|
|
||||||
|
|
||||||
AIM Coordinates:
|
|
||||||
1st number: +Y (left) (or -Y (right)?) (-Y?)
|
|
||||||
2nd number: +X (front) - 100% sure (-X?)
|
|
||||||
3rd number: +Z (up) - 100% sure
|
|
||||||
|
|
||||||
This is Z UP, LH axis system.
|
|
||||||
|
|
||||||
Also see https://twitter.com/FreyaHolmer/status/644881436982575104
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (AS)
|
// this is correct order and correct Y fix
|
||||||
{
|
READ(b, v.y);
|
||||||
case AxisSystem::MayaYUpZFrontRH:
|
READ(b, v.x);
|
||||||
// Y UP, Z FRONT (RH)
|
READ(b, v.z);
|
||||||
READ(b, v.x);
|
v.y = -v.y;
|
||||||
READ(b, v.z);
|
|
||||||
READ(b, v.y);
|
|
||||||
break;
|
|
||||||
case AxisSystem::AIM:
|
|
||||||
// Z UP, X FRONT (LH)
|
|
||||||
READ(b, v.y);
|
|
||||||
READ(b, v.x);
|
|
||||||
READ(b, v.z);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw SW_RUNTIME_ERROR("Unknown Axis System");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Y UP, X FRONT (LH?) (blender accepts such fbx)
|
|
||||||
z,x,y
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void aim_vector4::load(const buffer &b, uint32_t flags)
|
void aim_vector4::load(const buffer &b, uint32_t flags)
|
||||||
|
|
|
||||||
|
|
@ -306,4 +306,3 @@ struct model
|
||||||
};
|
};
|
||||||
|
|
||||||
float scale_mult();
|
float scale_mult();
|
||||||
int get_x_coordinate_id();
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue