Improve model loading.

This commit is contained in:
lzwdgc 2019-03-12 22:02:51 +03:00
parent 943f38dc96
commit f81baa57e4
4 changed files with 90 additions and 75 deletions

1
.gitignore vendored
View file

@ -2,6 +2,7 @@ win*
build build
bin bin
.cppan .cppan
doc
*.dll *.dll
*.lnk *.lnk

View file

@ -346,9 +346,9 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
float f; float f;
auto uc = modf(fabs(v.texture_coordinates.u), &f); auto uc = modf(fabs(v.texture_coordinates.u), &f);
auto vc = modf(fabs(v.texture_coordinates.v), &f); auto vc = modf(fabs(v.texture_coordinates.v), &f);
d_uv->GetDirectArray().Add(FbxVector2(uc, 1 - vc)); d_uv->GetDirectArray().Add(FbxVector2(uc, vc));
a_uv->GetDirectArray().Add(FbxVector2(uc, 1 - vc)); a_uv->GetDirectArray().Add(FbxVector2(uc, vc));
s_uv->GetDirectArray().Add(FbxVector2(uc, 1 - vc)); s_uv->GetDirectArray().Add(FbxVector2(uc, vc));
} }
// faces // faces

View file

@ -117,21 +117,20 @@ int get_x_coordinate_id()
} }
} }
template <typename T> static void load_translated(aim_vector3<float> &v, const buffer &b)
void aim_vector3<T>::load(const buffer &b)
{ {
/* /*
Our coord system: Our coord system:
^ z ^ z
| |
---> y ---> y
/ /
v x v x
AIM Coordinates: AIM Coordinates:
1st number: +Y (left) (or -Y (right)?) 1st number: +Y (left) (or -Y (right)?) (-Y?)
2nd number: +X (front) - 100% sure 2nd number: +X (front) - 100% sure (-X?)
3rd number: +Z (up) - 100% sure 3rd number: +Z (up) - 100% sure
This is Z UP, LH axis system. This is Z UP, LH axis system.
@ -143,15 +142,15 @@ void aim_vector3<T>::load(const buffer &b)
{ {
case AxisSystem::MayaYUpZFrontRH: case AxisSystem::MayaYUpZFrontRH:
// Y UP, Z FRONT (RH) // Y UP, Z FRONT (RH)
READ(b, base::x); READ(b, v.x);
READ(b, base::z); READ(b, v.z);
READ(b, base::y); READ(b, v.y);
break; break;
case AxisSystem::AIM: case AxisSystem::AIM:
// Z UP, X FRONT (LH) // Z UP, X FRONT (LH)
READ(b, base::y); READ(b, v.y);
READ(b, base::x); READ(b, v.x);
READ(b, base::z); READ(b, v.z);
break; break;
default: default:
throw SW_RUNTIME_ERROR("Unknown Axis System"); throw SW_RUNTIME_ERROR("Unknown Axis System");
@ -165,9 +164,12 @@ void aim_vector3<T>::load(const buffer &b)
void aim_vector4::load(const buffer &b, uint32_t flags) void aim_vector4::load(const buffer &b, uint32_t flags)
{ {
base::load(b); load_translated(*this, b);
if (flags & F_USE_W_COORDINATE) if (flags & F_WIND_TRANSFORM)
READ(b, w); {
float f;
READ(b, f);
}
} }
std::string aim_vector4::print() const std::string aim_vector4::print() const
@ -177,54 +179,55 @@ std::string aim_vector4::print() const
return s; return s;
} }
void vertex_normal::load(const buffer &b)
{
load_translated(*this, b);
}
void uv::load(const buffer &b)
{
READ(b, u);
READ(b, v);
v = 1 - v;
}
void vertex::load(const buffer &b, uint32_t flags) void vertex::load(const buffer &b, uint32_t flags)
{ {
coordinates.load(b, flags); coordinates.load(b, flags);
normal.load(b); normal.load(b);
//READ(b, normal); texture_coordinates.load(b);
READ(b, texture_coordinates);
} }
std::string vertex::printVertex(bool rotate_x_90) const void face::load(const buffer &b)
{ {
// rotate by 90 grad over Ox axis READ(b, x);
/*#define M_PI_2 1.57079632679489661923 READ(b, y);
Eigen::Vector3f x; READ(b, z);
x << -coordinates.x, coordinates.y, -coordinates.z; }
Eigen::AngleAxis<float> rx(M_PI_2, Eigen::Vector3f(1, 0, 0)); static String print_float(double v)
auto x2 = rx * x;*/ {
char buf[20];
snprintf(buf, sizeof(buf), "%.10f", v);
return buf;
};
std::string vertex::printVertex() const
{
std::string s; std::string s;
if (rotate_x_90) s = "v " +
{ print_float(coordinates.x * scale_mult())
// that rotation is really equivalent to exchanging y and z and z sign + " " + print_float(coordinates.y * scale_mult())
s = "v " + + " " + print_float(coordinates.z * scale_mult())
std::to_string(-coordinates.x * scale_mult()) + " " + //+ " " + print_float(coordinates.w)
std::to_string(coordinates.z * scale_mult()) + " " + ;
std::to_string(coordinates.y * scale_mult()) + " " +
std::to_string(coordinates.w)
;
}
else
{
s = "v " +
std::to_string(-coordinates.x * scale_mult()) + " " +
std::to_string(coordinates.y * scale_mult()) + " " +
std::to_string(-coordinates.z * scale_mult()) + " " +
std::to_string(coordinates.w)
;
}
return s; return s;
} }
std::string vertex::printNormal(bool rotate_x_90) const std::string vertex::printNormal() const
{ {
std::string s; std::string s;
if (rotate_x_90) s = "vn " + print_float(normal.x) + " " + print_float(normal.y) + " " + print_float(normal.z);
s = "vn " + std::to_string(-normal.x) + " " + std::to_string(-normal.z) + " " + std::to_string(normal.y);
else
s = "vn " + std::to_string(-normal.x) + " " + std::to_string(normal.y) + " " + std::to_string(-normal.z);
return s; return s;
} }
@ -234,7 +237,7 @@ std::string vertex::printTex() const
float i; float i;
auto u = modf(fabs(texture_coordinates.u), &i); auto u = modf(fabs(texture_coordinates.u), &i);
auto v = modf(fabs(texture_coordinates.v), &i); auto v = modf(fabs(texture_coordinates.v), &i);
s = "vt " + std::to_string(u) + " " + std::to_string(1 - v); s = "vt " + print_float(u) + " " + print_float(v);
return s; return s;
} }
@ -258,7 +261,7 @@ void damage_model::load(const buffer &b)
for (auto &v : vertices) for (auto &v : vertices)
v.load(b, flags); v.load(b, flags);
for (auto &t : faces) for (auto &t : faces)
READ(b, t); t.load(b);
} }
std::string mat_color::print() const std::string mat_color::print() const
@ -350,7 +353,7 @@ std::string block::printMtl() const
return s; return s;
} }
std::string block::printObj(int group_offset, bool rotate_x_90) const std::string block::printObj(int group_offset) const
{ {
std::string s; std::string s;
s += "usemtl " + h.name + "\n"; s += "usemtl " + h.name + "\n";
@ -359,16 +362,20 @@ std::string block::printObj(int group_offset, bool rotate_x_90) const
s += "s 1\n"; // still unk how to use s += "s 1\n"; // still unk how to use
s += "\n"; s += "\n";
s += "# " + std::to_string(vertices.size()) + " vertices\n";
for (auto &v : vertices) for (auto &v : vertices)
s += v.printVertex(rotate_x_90) + "\n"; s += v.printVertex() + "\n";
s += "\n"; s += "\n";
s += "# " + std::to_string(vertices.size()) + " vertex normals\n";
for (auto &v : vertices) for (auto &v : vertices)
s += v.printNormal(rotate_x_90) + "\n"; s += v.printNormal() + "\n";
s += "\n"; s += "\n";
s += "# " + std::to_string(vertices.size()) + " texture coords\n";
for (auto &v : vertices) for (auto &v : vertices)
s += v.printTex() + "\n"; s += v.printTex() + "\n";
s += "\n"; s += "\n";
s += "# " + std::to_string(vertices.size()) + " faces\n";
for (auto &t : faces) for (auto &t : faces)
{ {
auto x = std::to_string(t.x + 1 + group_offset); auto x = std::to_string(t.x + 1 + group_offset);
@ -502,7 +509,7 @@ void block::loadPayload(const buffer &data)
READ(data, rot); READ(data, rot);
READ(data, flags); READ(data, flags);
uint32_t n_vertex; uint32_t n_vertex;
uint32_t n_faces; // ??? edges? polygons? uint32_t n_faces; // ??? edges? polygons? triangles?
READ(data, n_vertex); READ(data, n_vertex);
vertices.resize(n_vertex); vertices.resize(n_vertex);
READ(data, n_faces); READ(data, n_faces);
@ -523,7 +530,7 @@ void block::loadPayload(const buffer &data)
{ {
n_faces *= 6; // 7 n_faces *= 6; // 7
auto faces2 = faces; decltype(faces) faces2;
faces2.resize(n_faces / 3); faces2.resize(n_faces / 3);
for (auto &t : faces2) for (auto &t : faces2)
READ(data, t); READ(data, t);
@ -532,7 +539,7 @@ void block::loadPayload(const buffer &data)
// maybe two winds anims? // maybe two winds anims?
// small wind and big wind? // small wind and big wind?
if (triangles_mult_7 && !unk11 && if (triangles_mult_7 && !unk11 &&
((flags & F_USE_W_COORDINATE) || flags == 0x112) ((flags & F_WIND_TRANSFORM) || flags == 0x112)
) )
{ {
read_more_faces(); read_more_faces();
@ -553,7 +560,7 @@ void block::loadPayload(const buffer &data)
else else
{ {
// unknown end of block // unknown end of block
auto triangles2 = faces; decltype(faces) triangles2;
auto d = data.end() - data.index(); auto d = data.end() - data.index();
triangles2.resize(d / sizeof(face)); triangles2.resize(d / sizeof(face));
for (auto &t : triangles2) for (auto &t : triangles2)
@ -655,7 +662,7 @@ void model::print(const std::string &fn) const
o << "\n"; o << "\n";
}; };
auto print_obj = [&](const auto &n, bool rotate_x_90 = false) auto print_obj = [&](const auto &n)
{ {
std::ofstream o(n); std::ofstream o(n);
title(o); title(o);
@ -667,7 +674,7 @@ void model::print(const std::string &fn) const
if (!b.canPrint()) if (!b.canPrint())
continue; continue;
o << b.printObj(n_vert, rotate_x_90) << "\n"; o << b.printObj(n_vert) << "\n";
n_vert += b.vertices.size(); n_vert += b.vertices.size();
} }
}; };
@ -678,8 +685,7 @@ void model::print(const std::string &fn) const
for (auto &b : blocks) for (auto &b : blocks)
m << b.printMtl() << "\n"; m << b.printMtl() << "\n";
print_obj(fn + "_fbx.obj"); print_obj(fn + ".obj");
print_obj(fn + "_ue4.obj", true);
} }
void model::save(yaml &root) const void model::save(yaml &root) const

View file

@ -33,7 +33,7 @@ class buffer;
enum enum
{ {
F_USE_W_COORDINATE = 0x4, // F_USE_QUANTERNION/F_QUANTERNION? F_WIND_TRANSFORM = 0x4,
}; };
enum class AdditionalParameter : uint32_t enum class AdditionalParameter : uint32_t
@ -83,8 +83,6 @@ template <typename T>
struct aim_vector3 : vector3<T> struct aim_vector3 : vector3<T>
{ {
using base = vector3<T>; using base = vector3<T>;
void load(const buffer &b);
}; };
struct aim_vector4 : aim_vector3<float> struct aim_vector4 : aim_vector3<float>
@ -97,26 +95,36 @@ struct aim_vector4 : aim_vector3<float>
void load(const buffer &b, uint32_t flags = 0); void load(const buffer &b, uint32_t flags = 0);
}; };
struct vertex_normal : aim_vector3<float>
{
void load(const buffer &b);
};
struct uv struct uv
{ {
float u; float u;
float v; float v;
void load(const buffer &b);
}; };
struct vertex struct vertex
{ {
aim_vector4 coordinates; aim_vector4 coordinates;
aim_vector3<float> normal; vertex_normal normal;
uv texture_coordinates; uv texture_coordinates;
void load(const buffer &b, uint32_t flags); void load(const buffer &b, uint32_t flags);
std::string printVertex(bool rotate_x_90 = false) const; std::string printVertex() const;
std::string printNormal(bool rotate_x_90 = false) const; std::string printNormal() const;
std::string printTex() const; std::string printTex() const;
}; };
using face = aim_vector3<uint16_t>; struct face : aim_vector3<uint16_t>
{
void load(const buffer &b);
};
struct animation struct animation
{ {
@ -279,7 +287,7 @@ struct block
void loadPayload(const buffer &b); void loadPayload(const buffer &b);
std::string printMtl() const; std::string printMtl() const;
std::string printObj(int group_offset, bool rotate_x_90 = false) const; std::string printObj(int group_offset) const;
block_info save(yaml &root) const; block_info save(yaml &root) const;
bool canPrint() const; bool canPrint() const;