LumixEngine/src/renderer/editor/fbx_importer.h

201 lines
4.8 KiB
C
Raw Normal View History

2018-08-05 18:00:30 +02:00
#pragma once
#include "engine/array.h"
#include "engine/geometry.h"
2019-06-13 17:26:52 +02:00
#include "engine/math.h"
2019-06-11 22:39:39 +02:00
#include "engine/os.h"
#include "engine/stream.h"
2018-08-05 18:00:30 +02:00
#include "engine/string.h"
#include "ofbx.h"
namespace Lumix
{
struct FBXImporter
{
struct ImportConfig
{
2018-10-14 17:46:42 +02:00
enum class Origin : int
{
SOURCE,
CENTER,
BOTTOM
};
2018-08-05 18:00:30 +02:00
const char* output_dir;
2019-06-16 21:22:27 +02:00
const char* base_path;
2018-08-05 18:00:30 +02:00
float mesh_scale;
2018-10-14 17:46:42 +02:00
Origin origin = Origin::SOURCE;
2018-08-05 18:00:30 +02:00
};
enum class Orientation
{
Y_UP,
Z_UP,
Z_MINUS_UP,
X_MINUS_UP,
X_UP
};
struct RotationKey
{
Quat rot;
float time;
u16 frame;
};
struct TranslationKey
{
Vec3 pos;
float time;
u16 frame;
};
struct Skin
{
float weights[4];
i16 joints[4];
int count = 0;
};
struct ImportAnimation
{
struct Split
{
int from_frame = 0;
int to_frame = 0;
StaticString<32> name;
};
explicit ImportAnimation(IAllocator& allocator)
: splits(allocator)
{}
const ofbx::AnimationStack* fbx = nullptr;
const ofbx::IScene* scene = nullptr;
Array<Split> splits;
StaticString<MAX_PATH_LENGTH> output_filename;
bool import = true;
int root_motion_bone_idx = -1;
};
struct ImportTexture
{
enum Type
{
DIFFUSE,
NORMAL,
COUNT
};
const ofbx::Texture* fbx = nullptr;
bool import = true;
bool to_dds = true;
bool is_valid = false;
StaticString<MAX_PATH_LENGTH> path;
StaticString<MAX_PATH_LENGTH> src;
};
struct ImportMaterial
{
const ofbx::Material* fbx = nullptr;
bool import = true;
bool alpha_cutout = false;
ImportTexture textures[ImportTexture::COUNT];
char shader[20];
};
struct ImportMesh
{
ImportMesh(IAllocator& allocator)
: vertex_data(allocator)
, indices(allocator)
{
}
const ofbx::Mesh* fbx = nullptr;
const ofbx::Material* fbx_mat = nullptr;
bool import = true;
bool import_physics = false;
int lod = 0;
2019-06-03 00:36:17 +02:00
int submesh = -1;
2019-06-11 22:39:39 +02:00
OutputMemoryStream vertex_data;
2018-08-05 18:00:30 +02:00
Array<int> indices;
AABB aabb;
float radius_squared;
2018-10-15 00:39:57 +02:00
Matrix transform_matrix = Matrix::IDENTITY;
2018-08-05 18:00:30 +02:00
};
FBXImporter(IAllocator& allocator);
~FBXImporter();
2019-06-16 23:16:55 +02:00
bool setSource(const char* base_dir, const char* filename);
2018-08-05 18:00:30 +02:00
void writeMaterials(const char* src, const ImportConfig& cfg);
2018-08-13 21:31:43 +02:00
void writeAnimations(const char* src, const ImportConfig& cfg);
void writeSubmodels(const char* dir, const char* basename, const ImportConfig& cfg);
2018-10-15 00:39:57 +02:00
void writePrefab(const char* src, const ImportConfig& cfg);
void writeModel(const char* dir, const char* basename, const char* ext, const ImportConfig& cfg);
2018-08-05 18:00:30 +02:00
2018-10-14 17:46:42 +02:00
const Array<ImportMesh>& getMeshes() const { return meshes; }
2019-06-03 00:36:17 +02:00
static void getImportMeshName(const ImportMesh& mesh, char (&name)[256]);
2018-11-08 22:11:02 +01:00
ofbx::IScene* getOFBXScene() { return scene; }
2018-10-14 17:46:42 +02:00
2018-08-05 18:00:30 +02:00
private:
const ofbx::Mesh* getAnyMeshFromBone(const ofbx::Object* node) const;
void gatherMaterials(const ofbx::Object* node, const char* src_dir);
void sortBones();
void gatherBones(const ofbx::IScene& scene);
void gatherAnimations(const ofbx::IScene& scene);
2019-06-11 22:39:39 +02:00
void writePackedVec3(const ofbx::Vec3& vec, const Matrix& mtx, OutputMemoryStream* blob) const;
2018-08-05 18:00:30 +02:00
void postprocessMeshes(const ImportConfig& cfg);
void gatherMeshes(ofbx::IScene* scene);
template <typename T> void write(const T& obj) { out_file.write(&obj, sizeof(obj)); }
void write(const void* ptr, size_t size) { out_file.write(ptr, size); }
void writeString(const char* str);
bool isSkinned(const ofbx::Mesh& mesh) const { return !ignore_skeleton && mesh.getGeometry()->getSkin() != nullptr; }
int getVertexSize(const ofbx::Mesh& mesh) const;
void fillSkinInfo(Array<Skin>& skinning, const ofbx::Mesh* mesh) const;
Vec3 fixRootOrientation(const Vec3& v) const;
Quat fixRootOrientation(const Quat& v) const;
Vec3 fixOrientation(const Vec3& v) const;
Quat fixOrientation(const Quat& v) const;
void writeGeometry();
2018-10-14 17:46:42 +02:00
void writeGeometry(int mesh_idx);
void writeMeshes(const char* src, int mesh_idx);
2018-08-05 18:00:30 +02:00
void writeSkeleton(const ImportConfig& cfg);
void writeLODs();
int getAttributeCount(const ofbx::Mesh& mesh) const;
bool areIndices16Bit(const ImportMesh& mesh) const;
void writeModelHeader();
2019-06-11 22:39:39 +02:00
void writePhysicsHeader(OS::OutputFile& file) const;
void writePhysicsTriMesh(OS::OutputFile& file);
2018-08-05 18:00:30 +02:00
bool writePhysics(const char* basename, const char* output_dir);
IAllocator& allocator;
Array<ImportMaterial> materials;
Array<ImportMesh> meshes;
Array<ImportAnimation> animations;
Array<const ofbx::Object*> bones;
ofbx::IScene* scene;
float lods_distances[4] = {-10, -100, -1000, -10000};
2019-06-23 14:01:08 +02:00
OutputMemoryStream out_file;
2018-08-05 18:00:30 +02:00
float time_scale = 1.0f;
float position_error = 0.1f;
float rotation_error = 0.01f;
float bounding_shape_scale = 1.0f;
bool to_dds = false;
bool cancel_mesh_transforms = false;
bool ignore_skeleton = false;
bool import_vertex_colors = true;
bool make_convex = false;
Orientation orientation = Orientation::Y_UP;
Orientation root_orientation = Orientation::Y_UP;
};
} // namespace Lumix