mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43:25 +00:00
More model data transformations.
This commit is contained in:
parent
7325952708
commit
baacacc44b
3 changed files with 208 additions and 138 deletions
|
|
@ -258,36 +258,36 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
||||||
static const char* gAmbientElementName = "AmbientUV";
|
static const char* gAmbientElementName = "AmbientUV";
|
||||||
static const char* gSpecularElementName = "SpecularUV";
|
static const char* gSpecularElementName = "SpecularUV";
|
||||||
|
|
||||||
auto create_socket_named = [&pScene](const std::string &name)
|
|
||||||
{
|
|
||||||
FbxNode *socket = FbxNode::Create(pScene, ("SOCKET_" + name).c_str());
|
|
||||||
auto n = FbxNull::Create(pScene, "");
|
|
||||||
socket->SetNodeAttribute(n);
|
|
||||||
pScene->GetRootNode()->AddChild(socket);
|
|
||||||
return socket;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto create_socket = [&create_socket_named](const auto &b, const std::string &name, bool mirror_y = false)
|
|
||||||
{
|
|
||||||
FbxVector4 c;
|
|
||||||
for (auto &v : b.vertices)
|
|
||||||
{
|
|
||||||
FbxVector4 x;
|
|
||||||
x.Set(v.coordinates.x * scale_mult(), v.coordinates.y * scale_mult(), v.coordinates.z * scale_mult(), v.coordinates.w);
|
|
||||||
c += x;
|
|
||||||
}
|
|
||||||
c /= b.vertices.size();
|
|
||||||
|
|
||||||
auto s = create_socket_named(name);
|
|
||||||
if (mirror_y) // y is the second coord, idx = 1
|
|
||||||
c.mData[1] = -c.mData[1];
|
|
||||||
s->LclTranslation.Set(c);
|
|
||||||
};
|
|
||||||
|
|
||||||
int engine_id = 0;
|
int engine_id = 0;
|
||||||
int fx_id = 0;
|
int fx_id = 0;
|
||||||
for (auto &b : model.blocks)
|
for (auto &b : model.blocks)
|
||||||
{
|
{
|
||||||
|
auto create_socket_named = [&pScene](const std::string &name)
|
||||||
|
{
|
||||||
|
FbxNode *socket = FbxNode::Create(pScene, ("SOCKET_" + name).c_str());
|
||||||
|
auto n = FbxNull::Create(pScene, "");
|
||||||
|
socket->SetNodeAttribute(n);
|
||||||
|
pScene->GetRootNode()->AddChild(socket);
|
||||||
|
return socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto create_socket = [&create_socket_named](const auto &b, const std::string &name, bool mirror_y = false)
|
||||||
|
{
|
||||||
|
FbxVector4 c;
|
||||||
|
for (auto &v : b.pmd.vertices)
|
||||||
|
{
|
||||||
|
FbxVector4 x;
|
||||||
|
x.Set(v.x * scale_mult(), v.y * scale_mult(), v.z * scale_mult(), v.w);
|
||||||
|
c += x;
|
||||||
|
}
|
||||||
|
c /= b.pmd.vertices.size();
|
||||||
|
|
||||||
|
auto s = create_socket_named(name);
|
||||||
|
if (mirror_y) // y is the second coord, idx = 1
|
||||||
|
c.mData[1] = -c.mData[1];
|
||||||
|
s->LclTranslation.Set(c);
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
if (b.isEngineFx())
|
if (b.isEngineFx())
|
||||||
{
|
{
|
||||||
|
|
@ -331,7 +331,7 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
||||||
node->SetShadingMode(FbxNode::eFullShading); // change?! was texture sh
|
node->SetShadingMode(FbxNode::eFullShading); // change?! was texture sh
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
m->InitControlPoints(b.vertices.size());
|
m->InitControlPoints(b.pmd.vertices.size());
|
||||||
|
|
||||||
// normals
|
// normals
|
||||||
auto normal = m->CreateElementNormal();
|
auto normal = m->CreateElementNormal();
|
||||||
|
|
@ -352,27 +352,32 @@ bool CreateScene(const model &model, const std::string &name, FbxManager* pSdkMa
|
||||||
auto s_uv = create_uv(gSpecularElementName);
|
auto s_uv = create_uv(gSpecularElementName);
|
||||||
|
|
||||||
// add vertices, normals, uvs
|
// add vertices, normals, uvs
|
||||||
for (const auto &[i,v] : enumerate(b.vertices))
|
SW_CHECK(b.pmd.vertices.size() == b.pmd.normals.size());
|
||||||
|
for (const auto &[i,v] : enumerate(b.pmd.vertices))
|
||||||
{
|
{
|
||||||
FbxVector4 cp(v.coordinates.x * scale_mult(), v.coordinates.y * scale_mult(), v.coordinates.z * scale_mult(), v.coordinates.w);
|
FbxVector4 cp(v.x * scale_mult(), v.y * scale_mult(), v.z * scale_mult(), v.w);
|
||||||
FbxVector4 n(v.normal.x, v.normal.y, v.normal.z);
|
FbxVector4 n(b.pmd.normals[i].x, b.pmd.normals[i].y, b.pmd.normals[i].z);
|
||||||
m->SetControlPointAt(cp, n, i);
|
m->SetControlPointAt(cp, n, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// uvs
|
||||||
|
for (const auto &[u,v] : b.pmd.uvs)
|
||||||
|
{
|
||||||
float f;
|
float f;
|
||||||
auto uc = modf(fabs(v.texture_coordinates.u), &f);
|
auto uc = modf(fabs(u), &f);
|
||||||
auto vc = modf(fabs(v.texture_coordinates.v), &f);
|
auto vc = modf(fabs(v), &f);
|
||||||
d_uv->GetDirectArray().Add(FbxVector2(uc, vc));
|
d_uv->GetDirectArray().Add(FbxVector2(uc, vc));
|
||||||
a_uv->GetDirectArray().Add(FbxVector2(uc, vc));
|
a_uv->GetDirectArray().Add(FbxVector2(uc, vc));
|
||||||
s_uv->GetDirectArray().Add(FbxVector2(uc, vc));
|
s_uv->GetDirectArray().Add(FbxVector2(uc, vc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// faces
|
// faces
|
||||||
for (auto &v : b.faces)
|
for (auto &v : b.pmd.faces)
|
||||||
{
|
{
|
||||||
// Set the control point indices of the bottom side of the pyramid
|
// Set the control point indices of the bottom side of the pyramid
|
||||||
m->BeginPolygon();
|
m->BeginPolygon();
|
||||||
for (auto i : v.vertex_list)
|
for (auto &i : v.points)
|
||||||
m->AddPolygon(i);
|
m->AddPolygon(i.vertex);
|
||||||
m->EndPolygon();
|
m->EndPolygon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,37 +171,18 @@ static aim_vector3<T> rotate(const aim_vector3<T> &in, AxisSystem rot_type)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string vertex::printVertex(AxisSystem as) const
|
void model_data::load(const buffer &b, uint32_t flags)
|
||||||
{
|
{
|
||||||
auto v = rotate(coordinates, as);
|
uint32_t n_vertex;
|
||||||
|
uint32_t n_faces;
|
||||||
std::string s;
|
READ(b, n_vertex);
|
||||||
s = "v " +
|
vertices.resize(n_vertex);
|
||||||
print_float(v.x * scale_mult())
|
READ(b, n_faces);
|
||||||
+ " " + print_float(v.y * scale_mult())
|
faces.resize(n_faces / 3);
|
||||||
+ " " + print_float(v.z * scale_mult())
|
for (auto &v : vertices)
|
||||||
//+ " " + print_float(coordinates.w)
|
v.load(b, flags);
|
||||||
;
|
for (auto &t : faces)
|
||||||
return s;
|
t.load(b);
|
||||||
}
|
|
||||||
|
|
||||||
std::string vertex::printNormal(AxisSystem as) const
|
|
||||||
{
|
|
||||||
auto v = rotate(normal, as);
|
|
||||||
|
|
||||||
std::string s;
|
|
||||||
s = "vn " + print_float(v.x) + " " + print_float(v.y) + " " + print_float(v.z);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string vertex::printTex() const
|
|
||||||
{
|
|
||||||
std::string s;
|
|
||||||
float i;
|
|
||||||
auto u = modf(fabs(texture_coordinates.u), &i);
|
|
||||||
auto v = modf(fabs(texture_coordinates.v), &i);
|
|
||||||
s = "vt " + print_float(u) + " " + print_float(v);
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void damage_model::load(const buffer &b)
|
void damage_model::load(const buffer &b)
|
||||||
|
|
@ -215,16 +196,7 @@ void damage_model::load(const buffer &b)
|
||||||
READ(b, t);
|
READ(b, t);
|
||||||
READ(b, unk6);
|
READ(b, unk6);
|
||||||
READ(b, flags);
|
READ(b, flags);
|
||||||
uint32_t n_vertex;
|
data.load(b, flags);
|
||||||
uint32_t n_faces;
|
|
||||||
READ(b, n_vertex);
|
|
||||||
vertices.resize(n_vertex);
|
|
||||||
READ(b, n_faces);
|
|
||||||
faces.resize(n_faces / 3);
|
|
||||||
for (auto &v : vertices)
|
|
||||||
v.load(b, flags);
|
|
||||||
for (auto &t : faces)
|
|
||||||
t.load(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mat_color::print() const
|
std::string mat_color::print() const
|
||||||
|
|
@ -316,21 +288,53 @@ std::string block::printMtl() const
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string print_vertices_and_faces(int group_offset, AxisSystem as,
|
static std::string printVertex(const aim_vector4 &coordinates, AxisSystem as)
|
||||||
const std::vector<vertex> &vertices, const std::vector<face> &faces)
|
{
|
||||||
|
auto v = rotate(coordinates, as);
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
s = "v " +
|
||||||
|
print_float(v.x * scale_mult())
|
||||||
|
+ " " + print_float(v.y * scale_mult())
|
||||||
|
+ " " + print_float(v.z * scale_mult())
|
||||||
|
//+ " " + print_float(coordinates.w)
|
||||||
|
;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string printNormal(const vertex_normal &normal, AxisSystem as)
|
||||||
|
{
|
||||||
|
auto v = rotate(normal, as);
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
s = "vn " + print_float(v.x) + " " + print_float(v.y) + " " + print_float(v.z);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string printTex(const uv &texture_coordinates)
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
float i;
|
||||||
|
auto u = modf(fabs(texture_coordinates.u), &i);
|
||||||
|
auto v = modf(fabs(texture_coordinates.v), &i);
|
||||||
|
s = "vt " + print_float(u) + " " + print_float(v);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string processed_model_data::print(int group_offset, AxisSystem as) const
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
s += "# " + std::to_string(vertices.size()) + " vertices\n";
|
s += "# " + std::to_string(vertices.size()) + " vertices\n";
|
||||||
for (auto &v : vertices)
|
for (auto &v : vertices)
|
||||||
s += v.printVertex(as) + "\n";
|
s += printVertex(v, as) + "\n";
|
||||||
s += "\n";
|
s += "\n";
|
||||||
s += "# " + std::to_string(vertices.size()) + " vertex normals\n";
|
s += "# " + std::to_string(normals.size()) + " vertex normals\n";
|
||||||
for (auto &v : vertices)
|
for (auto &n : normals)
|
||||||
s += v.printNormal(as) + "\n";
|
s += printNormal(n, as) + "\n";
|
||||||
s += "\n";
|
s += "\n";
|
||||||
s += "# " + std::to_string(vertices.size()) + " texture coords\n";
|
s += "# " + std::to_string(uvs.size()) + " texture coords\n";
|
||||||
for (auto &v : vertices)
|
for (auto &v : uvs)
|
||||||
s += v.printTex() + "\n";
|
s += printTex(v) + "\n";
|
||||||
s += "\n";
|
s += "\n";
|
||||||
|
|
||||||
s += "# " + std::to_string(vertices.size()) + " faces\n";
|
s += "# " + std::to_string(vertices.size()) + " faces\n";
|
||||||
|
|
@ -339,10 +343,14 @@ static std::string print_vertices_and_faces(int group_offset, AxisSystem as,
|
||||||
// no rotate here
|
// no rotate here
|
||||||
// it is not face operation
|
// it is not face operation
|
||||||
s += "f ";
|
s += "f ";
|
||||||
for (auto v : t.vertex_list)
|
for (auto &v : t.points)
|
||||||
{
|
{
|
||||||
auto x = std::to_string(v + 1 + group_offset);
|
std::string x;
|
||||||
x += "/" + x + "/" + x;
|
x += std::to_string(v.vertex + 1 + group_offset);
|
||||||
|
x += "/";
|
||||||
|
x += std::to_string(v.uv + 1 + group_offset); // uv goes second in .obj
|
||||||
|
x += "/";
|
||||||
|
x += std::to_string(v.normal + 1 + group_offset);
|
||||||
s += x + " ";
|
s += x + " ";
|
||||||
}
|
}
|
||||||
s += "\n";
|
s += "\n";
|
||||||
|
|
@ -350,8 +358,35 @@ static std::string print_vertices_and_faces(int group_offset, AxisSystem as,
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string block::printObj(int group_offset, AxisSystem as,
|
static processed_model_data process_block(const model_data &d)
|
||||||
const std::vector<vertex> &vertices, const std::vector<face> &faces) const
|
{
|
||||||
|
processed_model_data pmd;
|
||||||
|
pmd.vertices.reserve(d.vertices.size());
|
||||||
|
pmd.normals.reserve(d.vertices.size());
|
||||||
|
pmd.uvs.reserve(d.vertices.size());
|
||||||
|
pmd.faces.reserve(d.faces.size());
|
||||||
|
|
||||||
|
for (auto &v : d.vertices)
|
||||||
|
{
|
||||||
|
pmd.vertices.push_back(v.coordinates);
|
||||||
|
pmd.normals.push_back(v.normal);
|
||||||
|
pmd.uvs.push_back(v.texture_coordinates);
|
||||||
|
}
|
||||||
|
for (auto &v : d.faces)
|
||||||
|
{
|
||||||
|
processed_model_data::face f;
|
||||||
|
for (const auto &[i,idx] : enumerate(v.vertex_list))
|
||||||
|
{
|
||||||
|
f.points[i].vertex = idx;
|
||||||
|
f.points[i].normal = idx;
|
||||||
|
f.points[i].uv = idx;
|
||||||
|
}
|
||||||
|
pmd.faces.push_back(f);
|
||||||
|
}
|
||||||
|
return pmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string block::printObj(int group_offset, AxisSystem as) const
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
s += "usemtl " + h.name + "\n";
|
s += "usemtl " + h.name + "\n";
|
||||||
|
|
@ -360,15 +395,10 @@ std::string block::printObj(int group_offset, AxisSystem as,
|
||||||
s += "s 1\n"; // still unk how to use
|
s += "s 1\n"; // still unk how to use
|
||||||
s += "\n";
|
s += "\n";
|
||||||
|
|
||||||
s += print_vertices_and_faces(group_offset, as, vertices, faces);
|
s += pmd.print(group_offset, as);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string block::printObj(int group_offset, AxisSystem as) const
|
|
||||||
{
|
|
||||||
return printObj(group_offset, as, vertices, faces);
|
|
||||||
}
|
|
||||||
|
|
||||||
void block::header::texture::load(const buffer &b)
|
void block::header::texture::load(const buffer &b)
|
||||||
{
|
{
|
||||||
READ_STRING(b, name);
|
READ_STRING(b, name);
|
||||||
|
|
@ -422,6 +452,8 @@ void block::load(const buffer &b)
|
||||||
// else - pass current
|
// else - pass current
|
||||||
// no copy when buffer is created before
|
// no copy when buffer is created before
|
||||||
loadPayload(h.size == 0 ? b : data);
|
loadPayload(h.size == 0 ? b : data);
|
||||||
|
|
||||||
|
pmd = process_block(md);
|
||||||
}
|
}
|
||||||
|
|
||||||
void block::loadPayload(const buffer &data)
|
void block::loadPayload(const buffer &data)
|
||||||
|
|
@ -473,10 +505,10 @@ void block::loadPayload(const buffer &data)
|
||||||
READ(data, unk12);
|
READ(data, unk12);
|
||||||
READ(data, triangles_mult_7); // particle system?
|
READ(data, triangles_mult_7); // particle system?
|
||||||
|
|
||||||
/*if (unk7 != 0)
|
//if (unk7 != 0)
|
||||||
std::cout << "nonzero unk7 = " << unk7 << " in block " << h.name << "\n";
|
//std::cout << "nonzero unk7 = " << unk7 << " in block " << h.name << "\n";
|
||||||
if (unk9 != 0)
|
//if (unk9 != 0)
|
||||||
std::cout << "nonzero unk9 = " << unk9 << " in block " << h.name << "\n";*/
|
//std::cout << "nonzero unk9 = " << unk9 << " in block " << h.name << "\n";
|
||||||
//
|
//
|
||||||
|
|
||||||
READ(data, additional_params);
|
READ(data, additional_params);
|
||||||
|
|
@ -485,17 +517,7 @@ void block::loadPayload(const buffer &data)
|
||||||
damage_models.resize(n_damage_models);
|
damage_models.resize(n_damage_models);
|
||||||
READ(data, rot);
|
READ(data, rot);
|
||||||
READ(data, flags);
|
READ(data, flags);
|
||||||
uint32_t n_vertex;
|
md.load(data, flags);
|
||||||
uint32_t n_faces; // ??? edges? polygons? triangles?
|
|
||||||
READ(data, n_vertex);
|
|
||||||
vertices.resize(n_vertex);
|
|
||||||
READ(data, n_faces);
|
|
||||||
auto n_triangles = n_faces / 3;
|
|
||||||
for (auto &v : vertices)
|
|
||||||
v.load(data, flags);
|
|
||||||
faces.resize(n_triangles);
|
|
||||||
for (auto &t : faces)
|
|
||||||
t.load(data);
|
|
||||||
|
|
||||||
// animations
|
// animations
|
||||||
for (auto &a : animations)
|
for (auto &a : animations)
|
||||||
|
|
@ -505,9 +527,10 @@ void block::loadPayload(const buffer &data)
|
||||||
|
|
||||||
auto read_more_faces = [&]()
|
auto read_more_faces = [&]()
|
||||||
{
|
{
|
||||||
|
auto n_faces = md.faces.size();
|
||||||
n_faces *= 6; // 7
|
n_faces *= 6; // 7
|
||||||
|
|
||||||
decltype(faces) faces2;
|
decltype(md.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);
|
||||||
|
|
@ -537,7 +560,7 @@ void block::loadPayload(const buffer &data)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unknown end of block
|
// unknown end of block
|
||||||
decltype(faces) triangles2;
|
decltype(md.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)
|
||||||
|
|
@ -551,14 +574,17 @@ void block::loadPayload(const buffer &data)
|
||||||
throw std::logic_error(s);
|
throw std::logic_error(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto linkFaces(const std::vector<vertex> &vertices, const std::vector<face> &faces)
|
static processed_model_data linkFaces(const processed_model_data &d)
|
||||||
{
|
{
|
||||||
// reference implementation by Razum: https://pastebin.com/KewhggDj
|
// reference implementation by Razum: https://pastebin.com/KewhggDj
|
||||||
|
|
||||||
std::vector<vertex> vertices2;
|
processed_model_data pmd = d;
|
||||||
|
|
||||||
|
/*std::vector<vertex> vertices2;
|
||||||
vertices2.reserve(vertices.size());
|
vertices2.reserve(vertices.size());
|
||||||
std::unordered_map<short, short> repl;
|
std::unordered_map<short, short> vrepl, trepl;
|
||||||
repl.reserve(vertices.size());
|
vrepl.reserve(vertices.size());
|
||||||
|
trepl.reserve(vertices.size());
|
||||||
|
|
||||||
auto sz = vertices.size();
|
auto sz = vertices.size();
|
||||||
for (int i = 0; i < sz; i++)
|
for (int i = 0; i < sz; i++)
|
||||||
|
|
@ -570,10 +596,19 @@ static auto linkFaces(const std::vector<vertex> &vertices, const std::vector<fac
|
||||||
if (it == vertices2.end())
|
if (it == vertices2.end())
|
||||||
{
|
{
|
||||||
vertices2.push_back(vertices[i]);
|
vertices2.push_back(vertices[i]);
|
||||||
repl[i] = vertices2.size() - 1;
|
vrepl[i] = vertices2.size() - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
repl[i] = std::distance(vertices2.begin(), it);
|
vrepl[i] = std::distance(vertices2.begin(), it);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uv> uvs2;
|
||||||
|
uvs2.reserve(uvs.size());
|
||||||
|
for (auto &f : uvs)
|
||||||
|
{
|
||||||
|
// remove duplicates
|
||||||
|
if (std::find(uvs2.begin(), uvs2.end(), f) == uvs2.end())
|
||||||
|
uvs2.push_back(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<face> faces2;
|
std::vector<face> faces2;
|
||||||
|
|
@ -581,20 +616,18 @@ static auto linkFaces(const std::vector<vertex> &vertices, const std::vector<fac
|
||||||
for (auto f : faces)
|
for (auto f : faces)
|
||||||
{
|
{
|
||||||
for (auto &v : f.vertex_list)
|
for (auto &v : f.vertex_list)
|
||||||
v = repl[v];
|
v = vrepl[v];
|
||||||
// remove duplicates
|
// remove duplicates
|
||||||
if (std::find(faces2.begin(), faces2.end(), f) == faces2.end())
|
if (std::find(faces2.begin(), faces2.end(), f) == faces2.end())
|
||||||
faces2.push_back(f);
|
faces2.push_back(f);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return std::tuple{ vertices2, faces2 };
|
return pmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void block::linkFaces()
|
void block::linkFaces()
|
||||||
{
|
{
|
||||||
auto [v, f] = ::linkFaces(vertices, faces);
|
pmd = ::linkFaces(pmd);
|
||||||
vertices = v;
|
|
||||||
faces = f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool block::isEngineFx() const
|
bool block::isEngineFx() const
|
||||||
|
|
@ -617,8 +650,13 @@ bool block::canPrint() const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// collision object
|
// collision object
|
||||||
if (h.name.find("SHAPE") != h.name.npos)
|
if (h.name.find("SHAPE") != h.name.npos ||
|
||||||
|
h.name.find("shape") != h.name.npos
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//std::cerr << "shape detected!\n";
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// default
|
// default
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -627,7 +665,7 @@ bool block::canPrint() const
|
||||||
block::block_info block::save(yaml &root) const
|
block::block_info block::save(yaml &root) const
|
||||||
{
|
{
|
||||||
aim_vector4 min{ 1e6, 1e6, 1e6, 1e6 }, max{ -1e6, -1e6, -1e6, -1e6 };
|
aim_vector4 min{ 1e6, 1e6, 1e6, 1e6 }, max{ -1e6, -1e6, -1e6, -1e6 };
|
||||||
for (auto &v : vertices)
|
for (auto &v : md.vertices)
|
||||||
{
|
{
|
||||||
auto mm = [&v](auto &m, auto f)
|
auto mm = [&v](auto &m, auto f)
|
||||||
{
|
{
|
||||||
|
|
@ -704,7 +742,7 @@ void model::print(const std::string &fn, AxisSystem as) const
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
o << b.printObj(n_vert, as) << "\n";
|
o << b.printObj(n_vert, as) << "\n";
|
||||||
n_vert += b.vertices.size();
|
n_vert += b.md.vertices.size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,8 @@ struct uv
|
||||||
float v;
|
float v;
|
||||||
|
|
||||||
void load(const buffer &b);
|
void load(const buffer &b);
|
||||||
|
|
||||||
|
bool operator==(const uv &rhs) const { return std::tie(u, v) == std::tie(rhs.u, rhs.v); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vertex
|
struct vertex
|
||||||
|
|
@ -141,10 +143,6 @@ struct vertex
|
||||||
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(AxisSystem as) const;
|
|
||||||
std::string printNormal(AxisSystem as) const;
|
|
||||||
std::string printTex() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct face
|
struct face
|
||||||
|
|
@ -152,9 +150,41 @@ struct face
|
||||||
uint16_t vertex_list[3];
|
uint16_t vertex_list[3];
|
||||||
|
|
||||||
void load(const buffer &b);
|
void load(const buffer &b);
|
||||||
|
|
||||||
bool operator==(const face &rhs) const { return vertex_list == rhs.vertex_list; }
|
bool operator==(const face &rhs) const { return vertex_list == rhs.vertex_list; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct model_data
|
||||||
|
{
|
||||||
|
std::vector<vertex> vertices;
|
||||||
|
std::vector<face> faces; // triangles
|
||||||
|
|
||||||
|
void load(const buffer &b, uint32_t flags);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct processed_model_data
|
||||||
|
{
|
||||||
|
struct face
|
||||||
|
{
|
||||||
|
struct point
|
||||||
|
{
|
||||||
|
// indices
|
||||||
|
uint16_t vertex;
|
||||||
|
uint16_t normal;
|
||||||
|
uint16_t uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
point points[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<aim_vector4> vertices;
|
||||||
|
std::vector<vertex_normal> normals;
|
||||||
|
std::vector<uv> uvs;
|
||||||
|
std::vector<face> faces;
|
||||||
|
|
||||||
|
std::string print(int group_offset, AxisSystem as) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct animation
|
struct animation
|
||||||
{
|
{
|
||||||
// +1 +0.5 -0.5 +1
|
// +1 +0.5 -0.5 +1
|
||||||
|
|
@ -189,8 +219,7 @@ struct damage_model
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<uint16_t> model_polygons;
|
std::vector<uint16_t> model_polygons;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
std::vector<vertex> vertices;
|
model_data data;
|
||||||
std::vector<face> faces;
|
|
||||||
|
|
||||||
uint8_t unk6;
|
uint8_t unk6;
|
||||||
float unk8[3];
|
float unk8[3];
|
||||||
|
|
@ -296,8 +325,7 @@ struct block
|
||||||
additional_parameters additional_params;
|
additional_parameters additional_params;
|
||||||
rotation rot;
|
rotation rot;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
std::vector<vertex> vertices;
|
model_data md;
|
||||||
std::vector<face> faces; // triangles
|
|
||||||
|
|
||||||
// animations
|
// animations
|
||||||
std::vector<animation> animations;
|
std::vector<animation> animations;
|
||||||
|
|
@ -322,9 +350,8 @@ struct block
|
||||||
bool canPrint() const;
|
bool canPrint() const;
|
||||||
bool isEngineFx() const;
|
bool isEngineFx() const;
|
||||||
|
|
||||||
private:
|
//
|
||||||
std::string block::printObj(int group_offset, AxisSystem as,
|
processed_model_data pmd;
|
||||||
const std::vector<vertex> &vertices, const std::vector<face> &faces) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model
|
struct model
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue