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;
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
FbxManager* lSdkManager = NULL;
|
||||
|
|
@ -219,12 +269,11 @@ void model::printFbx(const std::string &fn) const
|
|||
// Prepare the FBX SDK.
|
||||
InitializeSdkObjects(lSdkManager, lScene);
|
||||
|
||||
// default is ???
|
||||
//FbxAxisSystem::MayaZUp.ConvertScene(lScene);
|
||||
|
||||
// Create the scene.
|
||||
CreateScene(*this, fn, lSdkManager, lScene);
|
||||
|
||||
ConvertScene(lScene);
|
||||
|
||||
SaveScene(lSdkManager, lScene, (fn + ".fbx").c_str());
|
||||
//SaveScene(lSdkManager, lScene, (fn + "_ue4.fbx").c_str());
|
||||
//if (all_formats)
|
||||
|
|
@ -249,7 +298,7 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
|||
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;
|
||||
for (auto &v : b.vertices)
|
||||
|
|
@ -261,12 +310,9 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
|||
c /= b.vertices.size();
|
||||
|
||||
auto s = create_socket_named(name);
|
||||
// here we must mirror 'first' number (original x)
|
||||
// it depends on what order was during loading
|
||||
if (mirror_x)
|
||||
c.mData[get_x_coordinate_id()] = -c.mData[get_x_coordinate_id()];
|
||||
if (mirror_y) // y is the second coord, idx = 1
|
||||
c.mData[1] = -c.mData[1];
|
||||
s->LclTranslation.Set(c);
|
||||
//s->LclScaling.Set(FbxDouble3(scale_mult(), scale_mult(), scale_mult()));
|
||||
};
|
||||
|
||||
int engine_id = 0;
|
||||
|
|
@ -339,9 +385,9 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
|||
// add vertices, normals, uvs
|
||||
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);
|
||||
m->SetControlPointAt(x, n, i);
|
||||
m->SetControlPointAt(cp, n, i);
|
||||
|
||||
float f;
|
||||
auto uc = modf(fabs(v.texture_coordinates.u), &f);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ bool silent = 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<bool> all_formats("af", cl::desc("All formats"));
|
||||
cl::opt<bool> all_formats("af", cl::desc("All formats (.obj, .fbx)"));
|
||||
|
||||
yaml root;
|
||||
cl::opt<bool> stats("i", cl::desc("Gather information from (models)"));
|
||||
|
|
|
|||
|
|
@ -84,82 +84,21 @@ std::string translate(const std::string &s)
|
|||
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)
|
||||
{
|
||||
/*
|
||||
Our coord system:
|
||||
|
||||
^ z
|
||||
|
|
||||
---> y
|
||||
/
|
||||
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
|
||||
AIM Coordinates (.mod file coord system, 100% sure):
|
||||
1st number: -Y (front, -ParityOdd)
|
||||
2nd number: +X (right, thus RH)
|
||||
3rd number: +Z (up)
|
||||
This is Z UP, RH axis system - eMax (same as eMayaZUp) in fbx.
|
||||
*/
|
||||
|
||||
switch (AS)
|
||||
{
|
||||
case AxisSystem::MayaYUpZFrontRH:
|
||||
// Y UP, Z FRONT (RH)
|
||||
READ(b, v.x);
|
||||
READ(b, v.z);
|
||||
READ(b, v.y);
|
||||
break;
|
||||
case AxisSystem::AIM:
|
||||
// Z UP, X FRONT (LH)
|
||||
// this is correct order and correct Y fix
|
||||
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
|
||||
*/
|
||||
v.y = -v.y;
|
||||
}
|
||||
|
||||
void aim_vector4::load(const buffer &b, uint32_t flags)
|
||||
|
|
|
|||
|
|
@ -306,4 +306,3 @@ struct model
|
|||
};
|
||||
|
||||
float scale_mult();
|
||||
int get_x_coordinate_id();
|
||||
|
|
|
|||
Loading…
Reference in a new issue