mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43:25 +00:00
Add simple mod reader.
This commit is contained in:
parent
986fd859d7
commit
f9f9cedef8
5 changed files with 268 additions and 93 deletions
|
|
@ -50,6 +50,10 @@ else()
|
|||
message(STATUS "provide fbx sdk path to build mod converter")
|
||||
endif()
|
||||
|
||||
file(GLOB mod_reader_src "mod_reader/*")
|
||||
add_executable(mod_reader ${mod_reader_src} mod_converter/model.cpp)
|
||||
target_link_libraries(mod_reader common)
|
||||
|
||||
file(GLOB mpj_loader_src "mpj_loader/*")
|
||||
add_executable(mpj_loader ${mpj_loader_src})
|
||||
target_link_libraries(mpj_loader common)
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager,
|
|||
if (!b.canPrint())
|
||||
continue;
|
||||
|
||||
auto block_name = name + "/" + b.name;
|
||||
auto block_name = name + "/" + b.h.name;
|
||||
|
||||
// mesh
|
||||
auto m = FbxMesh::Create(pSdkManager, block_name.c_str());
|
||||
|
|
@ -296,10 +296,10 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager,
|
|||
{
|
||||
FbxString lMaterialName = block_name.c_str();
|
||||
FbxString lShadingName = "Phong";
|
||||
FbxDouble3 lAmbientColor(b.mat.ambient.x, b.mat.ambient.y, b.mat.ambient.z);
|
||||
FbxDouble3 lSpecularColor(b.mat.specular.x, b.mat.specular.y, b.mat.specular.z);
|
||||
FbxDouble3 lDiffuseColor(b.mat.diffuse.x, b.mat.diffuse.y, b.mat.diffuse.z);
|
||||
FbxDouble3 lEmissiveColor(b.mat.emissive.x, b.mat.emissive.y, b.mat.emissive.z);
|
||||
FbxDouble3 lAmbientColor(b.mat.ambient.r, b.mat.ambient.g, b.mat.ambient.b);
|
||||
FbxDouble3 lSpecularColor(b.mat.specular.r, b.mat.specular.g, b.mat.specular.b);
|
||||
FbxDouble3 lDiffuseColor(b.mat.diffuse.r, b.mat.diffuse.g, b.mat.diffuse.b);
|
||||
FbxDouble3 lEmissiveColor(b.mat.emissive.r, b.mat.emissive.g, b.mat.emissive.b);
|
||||
|
||||
FbxLayer* lLayer = m->GetLayer(0);
|
||||
|
||||
|
|
@ -322,14 +322,14 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager,
|
|||
|
||||
// Generate primary and secondary colors.
|
||||
lMaterial->Emissive.Set(lEmissiveColor);
|
||||
//lMaterial->EmissiveFactor.Set(b.material.emissive.x);
|
||||
lMaterial->EmissiveFactor.Set(b.mat.emissive.r);
|
||||
|
||||
lMaterial->Ambient.Set(lAmbientColor);
|
||||
//lMaterial->AmbientFactor.Set(b.mat.ambient.x);
|
||||
lMaterial->AmbientFactor.Set(b.mat.ambient.r);
|
||||
|
||||
// Add texture for diffuse channel
|
||||
lMaterial->Diffuse.Set(lDiffuseColor);
|
||||
//lMaterial->DiffuseFactor.Set(b.mat.diffuse.x);
|
||||
lMaterial->DiffuseFactor.Set(b.mat.diffuse.r);
|
||||
|
||||
//lMaterial->TransparencyFactor.Set(0.4);
|
||||
//lMaterial->ShadingModel.Set(lShadingName);
|
||||
|
|
@ -340,42 +340,40 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager,
|
|||
node->AddMaterial(lMaterial);
|
||||
}
|
||||
|
||||
FbxFileTexture* lTexture;
|
||||
|
||||
// Set texture properties.
|
||||
lTexture = FbxFileTexture::Create(pScene, "Diffuse Texture");
|
||||
lTexture->SetFileName((b.tex_mask + texture_extension).c_str()); // Resource file is in current directory.
|
||||
lTexture->SetTextureUse(FbxTexture::eStandard);
|
||||
lTexture->SetMappingType(FbxTexture::eUV);
|
||||
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
|
||||
lTexture->UVSet.Set(gDiffuseElementName);
|
||||
if (lMaterial)
|
||||
lMaterial->Diffuse.ConnectSrcObject(lTexture);
|
||||
|
||||
// Set texture properties.
|
||||
lTexture = FbxFileTexture::Create(pScene, "Ambient Texture");
|
||||
lTexture->SetFileName((b.tex_mask + texture_extension).c_str()); // Resource file is in current directory.
|
||||
lTexture->SetTextureUse(FbxTexture::eStandard);
|
||||
lTexture->SetMappingType(FbxTexture::eUV);
|
||||
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
|
||||
lTexture->UVSet.Set(gAmbientElementName);
|
||||
if (lMaterial)
|
||||
lMaterial->Ambient.ConnectSrcObject(lTexture);
|
||||
|
||||
// Set texture properties.
|
||||
lTexture = FbxFileTexture::Create(pScene, "Specular Texture");
|
||||
lTexture->SetFileName((b.tex_spec + texture_extension).c_str()); // Resource file is in current directory.
|
||||
lTexture->SetTextureUse(FbxTexture::eStandard);
|
||||
lTexture->SetMappingType(FbxTexture::eUV);
|
||||
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
|
||||
lTexture->UVSet.Set(gSpecularElementName);
|
||||
if (lMaterial)
|
||||
lMaterial->Specular.ConnectSrcObject(lTexture);
|
||||
|
||||
|
||||
if (b.mat_type != MaterialType::MaterialOnly)
|
||||
{
|
||||
FbxFileTexture* lTexture;
|
||||
|
||||
// Set texture properties.
|
||||
lTexture = FbxFileTexture::Create(pScene, "Diffuse Texture");
|
||||
lTexture->SetFileName((b.h.tex_mask + texture_extension).c_str()); // Resource file is in current directory.
|
||||
lTexture->SetTextureUse(FbxTexture::eStandard);
|
||||
lTexture->SetMappingType(FbxTexture::eUV);
|
||||
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
|
||||
lTexture->UVSet.Set(gDiffuseElementName);
|
||||
if (lMaterial)
|
||||
lMaterial->Diffuse.ConnectSrcObject(lTexture);
|
||||
|
||||
// Set texture properties.
|
||||
lTexture = FbxFileTexture::Create(pScene, "Ambient Texture");
|
||||
lTexture->SetFileName((b.h.tex_mask + texture_extension).c_str()); // Resource file is in current directory.
|
||||
lTexture->SetTextureUse(FbxTexture::eStandard);
|
||||
lTexture->SetMappingType(FbxTexture::eUV);
|
||||
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
|
||||
lTexture->UVSet.Set(gAmbientElementName);
|
||||
if (lMaterial)
|
||||
lMaterial->Ambient.ConnectSrcObject(lTexture);
|
||||
|
||||
// Set texture properties.
|
||||
lTexture = FbxFileTexture::Create(pScene, "Specular Texture");
|
||||
lTexture->SetFileName((b.h.tex_spec + texture_extension).c_str()); // Resource file is in current directory.
|
||||
lTexture->SetTextureUse(FbxTexture::eStandard);
|
||||
lTexture->SetMappingType(FbxTexture::eUV);
|
||||
lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial);
|
||||
lTexture->UVSet.Set(gSpecularElementName);
|
||||
if (lMaterial)
|
||||
lMaterial->Specular.ConnectSrcObject(lTexture);
|
||||
}
|
||||
|
||||
// add smoothing groups
|
||||
FbxGeometryConverter lGeometryConverter(pSdkManager);
|
||||
|
|
@ -383,7 +381,6 @@ bool CreateScene(model &model, const std::string &name, FbxManager* pSdkManager,
|
|||
//convert soft/hard edge info to smoothing group info
|
||||
lGeometryConverter.ComputePolygonSmoothingFromEdgeSmoothing(m);
|
||||
|
||||
|
||||
//
|
||||
pScene->GetRootNode()->AddChild(node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
#include <buffer.h>
|
||||
|
||||
#include <fbxsdk.h>
|
||||
|
||||
//#include <Eigen/Core>
|
||||
//#include <Eigen/Dense>
|
||||
|
||||
|
|
@ -235,6 +233,13 @@ void damage_model::load(const buffer &b)
|
|||
READ(b, t);
|
||||
}
|
||||
|
||||
std::string mat_color::print() const
|
||||
{
|
||||
string s;
|
||||
s += to_string(r) + " " + to_string(g) + " " + to_string(b);
|
||||
return s;
|
||||
}
|
||||
|
||||
void material::load(const buffer &b)
|
||||
{
|
||||
READ(b, diffuse);
|
||||
|
|
@ -245,9 +250,12 @@ void material::load(const buffer &b)
|
|||
|
||||
auto delim_by_3 = [](auto &v)
|
||||
{
|
||||
v.x /= 3.0f;
|
||||
v.y /= 3.0f;
|
||||
v.z /= 3.0f;
|
||||
//if (v.r > 1)
|
||||
//v.r /= 3.0f;
|
||||
//if (v.g > 1)
|
||||
//v.g /= 3.0f;
|
||||
//if (v.b > 1)
|
||||
//v.b /= 3.0f;
|
||||
};
|
||||
|
||||
// in aim - those values lie in interval [0,3] instead of [0,1]
|
||||
|
|
@ -292,7 +300,7 @@ void animation::segment::loadData(const buffer &b)
|
|||
std::string block::printMtl() const
|
||||
{
|
||||
string s;
|
||||
s += "newmtl " + name + "\n";
|
||||
s += "newmtl " + h.name + "\n";
|
||||
s += "\n";
|
||||
s += "Ka " + mat.ambient.print() + "\n";
|
||||
s += "Kd " + mat.diffuse.print() + "\n";
|
||||
|
|
@ -301,14 +309,14 @@ std::string block::printMtl() const
|
|||
// d 1.0
|
||||
// illum
|
||||
s += "\n";
|
||||
if (string(tex_mask) != "_DEFAULT_")
|
||||
s += "map_Ka " + string(tex_mask) + texture_extension + "\n";
|
||||
if (string(tex_mask) != "_DEFAULT_")
|
||||
s += "map_Kd " + string(tex_mask) + texture_extension + "\n";
|
||||
if (string(tex_spec) != "_DEFAULT_")
|
||||
s += "map_Ks " + string(tex_spec) + texture_extension + "\n";
|
||||
if (string(tex_spec) != "_DEFAULT_")
|
||||
s += "map_Ns " + string(tex_spec) + texture_extension + "\n";
|
||||
if (h.tex_mask != "_DEFAULT_")
|
||||
s += "map_Ka " + h.tex_mask + texture_extension + "\n";
|
||||
if (h.tex_mask != "_DEFAULT_")
|
||||
s += "map_Kd " + h.tex_mask + texture_extension + "\n";
|
||||
if (h.tex_spec != "_DEFAULT_")
|
||||
s += "map_Ks " + h.tex_spec + texture_extension + "\n";
|
||||
if (h.tex_spec != "_DEFAULT_")
|
||||
s += "map_Ns " + h.tex_spec + texture_extension + "\n";
|
||||
s += "\n";
|
||||
return s;
|
||||
}
|
||||
|
|
@ -316,9 +324,9 @@ std::string block::printMtl() const
|
|||
std::string block::printObj(int group_offset, bool rotate_x_90) const
|
||||
{
|
||||
string s;
|
||||
s += "usemtl " + name + "\n";
|
||||
s += "usemtl " + h.name + "\n";
|
||||
s += "\n";
|
||||
s += "g " + name + "\n";
|
||||
s += "g " + h.name + "\n";
|
||||
s += "s 1\n"; // still unk how to use
|
||||
s += "\n";
|
||||
|
||||
|
|
@ -348,9 +356,8 @@ std::string block::printObj(int group_offset, bool rotate_x_90) const
|
|||
return s;
|
||||
}
|
||||
|
||||
void block::load(const buffer &b)
|
||||
void block::header::load(const buffer &b)
|
||||
{
|
||||
// header
|
||||
READ(b, type);
|
||||
READ_STRING(b, name);
|
||||
name = translate(name);
|
||||
|
|
@ -363,17 +370,27 @@ void block::load(const buffer &b)
|
|||
READ(b, unk3);
|
||||
READ(b, size);
|
||||
READ(b, unk4);
|
||||
}
|
||||
|
||||
if (size == 0) // critical error!!! cannot survive
|
||||
void block::load(const buffer &b)
|
||||
{
|
||||
h.load(b);
|
||||
|
||||
if (h.size == 0) // critical error!!! cannot survive
|
||||
throw std::runtime_error("model file has bad block size field (size == 0)");
|
||||
|
||||
// data
|
||||
buffer data = buffer(b, size);
|
||||
buffer data = buffer(b, h.size);
|
||||
|
||||
// we cannot process this type at the moment
|
||||
if (type == BlockType::ParticleEmitter)
|
||||
if (h.type == BlockType::ParticleEmitter)
|
||||
return;
|
||||
|
||||
loadPayload(data);
|
||||
}
|
||||
|
||||
void block::loadPayload(const buffer &data)
|
||||
{
|
||||
// anims
|
||||
uint32_t n_animations;
|
||||
READ(data, n_animations);
|
||||
|
|
@ -420,7 +437,7 @@ void block::load(const buffer &b)
|
|||
for (auto &dm : damage_models)
|
||||
dm.load(data);
|
||||
|
||||
string s = "extraction error: block #" + std::string(name);
|
||||
string s = "extraction error: block #" + std::string(h.name);
|
||||
if (!data.eof())
|
||||
{
|
||||
cerr << s << "\n";
|
||||
|
|
@ -442,11 +459,11 @@ void block::load(const buffer &b)
|
|||
|
||||
bool block::canPrint() const
|
||||
{
|
||||
if (type == BlockType::ParticleEmitter)
|
||||
if (h.type == BlockType::ParticleEmitter)
|
||||
return false;
|
||||
if (type != BlockType::VisibleObject)
|
||||
if (h.type != BlockType::VisibleObject)
|
||||
return false;
|
||||
if (!(all_lods == 15 || LODs.lod1))
|
||||
if (!(h.all_lods == 15 || h.LODs.lod1))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,12 +150,22 @@ struct damage_model
|
|||
virtual void load(const buffer &b);
|
||||
};
|
||||
|
||||
struct mat_color
|
||||
{
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float alpha;
|
||||
|
||||
std::string print() const;
|
||||
};
|
||||
|
||||
struct material
|
||||
{
|
||||
aim_vector4 ambient;
|
||||
aim_vector4 diffuse;
|
||||
aim_vector4 specular;
|
||||
aim_vector4 emissive;
|
||||
mat_color ambient;
|
||||
mat_color diffuse;
|
||||
mat_color specular;
|
||||
mat_color emissive;
|
||||
float power;
|
||||
|
||||
void load(const buffer &b);
|
||||
|
|
@ -176,26 +186,40 @@ struct additional_parameters
|
|||
|
||||
struct block
|
||||
{
|
||||
// header
|
||||
BlockType type;
|
||||
std::string name;
|
||||
std::string tex_mask;
|
||||
std::string tex_spec;
|
||||
std::string tex3;
|
||||
std::string tex4;
|
||||
union // LODs
|
||||
struct header
|
||||
{
|
||||
struct
|
||||
BlockType type;
|
||||
std::string name;
|
||||
std::string tex_mask;
|
||||
std::string tex_spec;
|
||||
std::string tex3;
|
||||
std::string tex4;
|
||||
union // LODs
|
||||
{
|
||||
uint8_t lod1 : 1;
|
||||
uint8_t lod2 : 1;
|
||||
uint8_t lod3 : 1;
|
||||
uint8_t lod4 : 1;
|
||||
uint8_t : 4;
|
||||
} LODs;
|
||||
uint32_t all_lods;
|
||||
struct
|
||||
{
|
||||
uint8_t lod1 : 1;
|
||||
uint8_t lod2 : 1;
|
||||
uint8_t lod3 : 1;
|
||||
uint8_t lod4 : 1;
|
||||
uint8_t : 4;
|
||||
} LODs;
|
||||
uint32_t all_lods;
|
||||
};
|
||||
|
||||
// stuff
|
||||
uint32_t size;
|
||||
|
||||
// unk
|
||||
uint32_t unk2[3];
|
||||
uint32_t unk3;
|
||||
uint32_t unk4[10];
|
||||
|
||||
void load(const buffer &b);
|
||||
};
|
||||
|
||||
header h;
|
||||
|
||||
// data
|
||||
material mat;
|
||||
MaterialType mat_type;
|
||||
|
|
@ -216,13 +240,7 @@ struct block
|
|||
std::vector<animation> animations;
|
||||
std::vector<damage_model> damage_models;
|
||||
|
||||
// stuff
|
||||
uint32_t size;
|
||||
|
||||
// unk
|
||||
uint32_t unk2[3];
|
||||
uint16_t unk3[2];
|
||||
uint32_t unk4[10];
|
||||
uint32_t unk7;
|
||||
float unk9;
|
||||
uint32_t unk10;
|
||||
|
|
@ -231,6 +249,7 @@ struct block
|
|||
uint32_t unk12;
|
||||
|
||||
void load(const buffer &b);
|
||||
void loadPayload(const buffer &b);
|
||||
std::string printMtl() const;
|
||||
std::string printObj(int group_offset, bool rotate_x_90 = false) const;
|
||||
|
||||
|
|
|
|||
138
src/mod_reader/mod_reader.cpp
Normal file
138
src/mod_reader/mod_reader.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* AIM mod_converter
|
||||
* Copyright (C) 2015 lzwdgc
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include <buffer.h>
|
||||
#include "../mod_converter/model.h"
|
||||
|
||||
#include <primitives/filesystem.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// options
|
||||
bool all_formats = false;
|
||||
bool silent = false;
|
||||
bool printMaxPolygonBlock = false;
|
||||
path p;
|
||||
|
||||
bool parse_cmd(int argc, char *argv[]);
|
||||
|
||||
void convert_model(const path &fn)
|
||||
{
|
||||
buffer b(read_file(fn));
|
||||
block bl;
|
||||
bl.loadPayload(b);
|
||||
|
||||
if (!b.eof())
|
||||
{
|
||||
stringstream ss;
|
||||
ss << hex << b.index() << " != " << hex << b.size();
|
||||
throw std::logic_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
try
|
||||
{
|
||||
if (argc < 2 || !parse_cmd(argc, argv))
|
||||
{
|
||||
printf("Usage: %s [OPTIONS] {model_file,model_dir}\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (fs::is_regular_file(p))
|
||||
convert_model(p);
|
||||
else if (fs::is_directory(p))
|
||||
{
|
||||
auto files = enumerate_files(p, false);
|
||||
for (auto &f : files)
|
||||
{
|
||||
if (f.has_extension())
|
||||
continue;
|
||||
std::cout << "processing: " << f << "\n";
|
||||
convert_model(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("Bad fs object");
|
||||
return 0;
|
||||
}
|
||||
catch (std::runtime_error &e)
|
||||
{
|
||||
if (silent)
|
||||
return 1;
|
||||
string error;
|
||||
error += p.string();
|
||||
error += "\n";
|
||||
error += "fatal error: ";
|
||||
error += e.what();
|
||||
error += "\n";
|
||||
ofstream ofile(p.string() + ".error.txt");
|
||||
ofile << error;
|
||||
return 1;
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
if (silent)
|
||||
return 1;
|
||||
printf("%s\n", p.string().c_str());
|
||||
printf("error: %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (silent)
|
||||
return 1;
|
||||
printf("%s\n", p.string().c_str());
|
||||
printf("error: unknown exception\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool parse_cmd(int argc, char *argv[])
|
||||
{
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
auto arg = argv[i];
|
||||
if (*arg != '-')
|
||||
{
|
||||
if (i != argc - 1)
|
||||
return false;
|
||||
p = arg;
|
||||
continue;
|
||||
}
|
||||
switch (arg[1])
|
||||
{
|
||||
case 'a':
|
||||
all_formats = true;
|
||||
break;
|
||||
case 's':
|
||||
silent = true;
|
||||
break;
|
||||
case 'm':
|
||||
printMaxPolygonBlock = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Loading…
Reference in a new issue