Added Mesh Compression Import Options

Fleshed out the "Optimize Mesh" options found in the mesh import UI
Gave a checkbox to every vertex attribute that can be compressed

Surfaced option to enable/disable Octahedral compression for
normal/tangent vectors

Also surfaces the vertex position compression option which previously
inaccessible because the defaults did not compress vertex positions

Supports all current importers (obj, fbx, collada, gltf)
This commit is contained in:
Omar El Sheikh 2021-05-10 16:51:11 -04:00
parent 18c185bd42
commit 203295f17d
16 changed files with 71 additions and 62 deletions

View file

@ -47,6 +47,7 @@
<argument index="0" name="path" type="String" />
<argument index="1" name="flags" type="int" />
<argument index="2" name="bake_fps" type="int" />
<argument index="3" name="compress_flags" type="int" />
<description>
</description>
</method>
@ -70,7 +71,5 @@
</constant>
<constant name="IMPORT_MATERIALS_IN_INSTANCES" value="1024">
</constant>
<constant name="IMPORT_USE_COMPRESSION" value="2048">
</constant>
</constants>
</class>

View file

@ -86,10 +86,10 @@ struct ColladaImport {
Error _populate_skeleton(Skeleton *p_skeleton, Collada::Node *p_node, int &r_bone, int p_parent);
Error _create_scene_skeletons(Collada::Node *p_node);
Error _create_scene(Collada::Node *p_node, Spatial *p_parent);
Error _create_resources(Collada::Node *p_node, bool p_use_compression);
Error _create_resources(Collada::Node *p_node, uint32_t p_use_compression);
Error _create_material(const String &p_target);
Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes = Vector<Ref<ArrayMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false);
Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false, bool p_use_compression = false);
Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes = Vector<Ref<ArrayMesh>>(), uint32_t p_use_compression = 0, bool p_use_mesh_material = false);
Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false, uint32_t p_use_compression = 0);
void _fix_param_animation_tracks();
void create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks);
void create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks);
@ -451,7 +451,7 @@ Error ColladaImport::_create_material(const String &p_target) {
return OK;
}
Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) {
Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes, uint32_t p_use_compression, bool p_use_mesh_material) {
bool local_xform_mirror = p_local_xform.basis.determinant() < 0;
if (p_morph_data) {
@ -988,7 +988,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
mr.push_back(a);
}
p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, p_use_compression ? Mesh::ARRAY_COMPRESS_DEFAULT : Mesh::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION);
p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, p_use_compression);
if (material.is_valid()) {
if (p_use_mesh_material) {
@ -1008,7 +1008,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
return OK;
}
Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compression) {
Error ColladaImport::_create_resources(Collada::Node *p_node, uint32_t p_use_compression) {
if (p_node->type == Collada::Node::TYPE_GEOMETRY && node_map.has(p_node->id)) {
Spatial *node = node_map[p_node->id].node;
Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry *>(p_node);
@ -1247,7 +1247,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
return OK;
}
Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_tangents, bool p_use_compression) {
Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_tangents, uint32_t p_use_compression) {
Error err = collada.load(p_path, p_flags);
ERR_FAIL_COND_V_MSG(err, err, "Cannot load file '" + p_path + "'.");
@ -1711,7 +1711,7 @@ uint32_t EditorSceneImporterCollada::get_import_flags() const {
void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("dae");
}
Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err) {
ColladaImport state;
uint32_t flags = Collada::IMPORT_FLAG_SCENE;
if (p_flags & IMPORT_ANIMATION) {
@ -1721,7 +1721,7 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
state.use_mesh_builtin_materials = !(p_flags & IMPORT_MATERIALS_IN_INSTANCES);
state.bake_fps = p_bake_fps;
Error err = state.load(p_path, flags, p_flags & EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS, p_flags & EditorSceneImporter::IMPORT_USE_COMPRESSION);
Error err = state.load(p_path, flags, p_flags & EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS, p_compress_flags);
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "Cannot load scene from file '" + p_path + "'.");

View file

@ -39,7 +39,7 @@ class EditorSceneImporterCollada : public EditorSceneImporter {
public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr);
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
EditorSceneImporterCollada();

View file

@ -200,7 +200,7 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati
return OK;
}
static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, Vector3 p_offset_mesh, List<String> *r_missing_deps) {
static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_single_mesh, bool p_generate_tangents, int p_compress_flags, Vector3 p_scale_mesh, Vector3 p_offset_mesh, List<String> *r_missing_deps) {
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path));
@ -210,7 +210,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
bool generate_tangents = p_generate_tangents;
Vector3 scale_mesh = p_scale_mesh;
Vector3 offset_mesh = p_offset_mesh;
int mesh_flags = p_optimize ? Mesh::ARRAY_COMPRESS_DEFAULT : Mesh::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION;
Vector<Vector3> vertices;
Vector<Vector3> normals;
@ -348,7 +347,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
surf_tool->set_material(material_map[current_material_library][current_material]);
}
mesh = surf_tool->commit(mesh, mesh_flags);
mesh = surf_tool->commit(mesh, p_compress_flags);
if (current_material != String()) {
mesh->surface_set_name(mesh->get_surface_count() - 1, current_material.get_basename());
@ -411,10 +410,10 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
return OK;
}
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err) {
List<Ref<Mesh>> meshes;
Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, p_flags & IMPORT_USE_COMPRESSION, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps);
Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, p_compress_flags, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps);
if (err != OK) {
if (r_err) {
@ -478,7 +477,8 @@ void ResourceImporterOBJ::get_import_options(List<ImportOption> *r_options, int
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "scale_mesh"), Vector3(1, 1, 1)));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "offset_mesh"), Vector3(0, 0, 0)));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "optimize_mesh"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "octahedral_compression"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "optimize_mesh_flags", PROPERTY_HINT_FLAGS, "Vertex,Normal,Tangent,Color,TexUV,TexUV2,Bones,Weights,Index"), VS::ARRAY_COMPRESS_DEFAULT >> VS::ARRAY_COMPRESS_BASE));
}
bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
@ -487,7 +487,11 @@ bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Ma
Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
List<Ref<Mesh>> meshes;
Error err = _parse_obj(p_source_file, meshes, true, p_options["generate_tangents"], p_options["optimize_mesh"], p_options["scale_mesh"], p_options["offset_mesh"], nullptr);
uint32_t compress_flags = int(p_options["optimize_mesh_flags"]) << VS::ARRAY_COMPRESS_BASE;
if (bool(p_options["octahedral_compression"])) {
compress_flags |= VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION;
}
Error err = _parse_obj(p_source_file, meshes, true, p_options["generate_tangents"], compress_flags, p_options["scale_mesh"], p_options["offset_mesh"], nullptr);
ERR_FAIL_COND_V(err != OK, err);
ERR_FAIL_COND_V(meshes.size() != 1, ERR_BUG);

View file

@ -39,7 +39,7 @@ class EditorOBJImporter : public EditorSceneImporter {
public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
EditorOBJImporter();

View file

@ -64,7 +64,7 @@ void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
ERR_FAIL();
}
Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err) {
if (get_script_instance()) {
return get_script_instance()->call("_import_scene", p_path, p_flags, p_bake_fps);
}
@ -83,8 +83,8 @@ Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint3
//for documenters, these functions are useful when an importer calls an external conversion helper (like, fbx2gltf),
//and you want to load the resulting file
Node *EditorSceneImporter::import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
return ResourceImporterScene::get_singleton()->import_scene_from_other_importer(this, p_path, p_flags, p_bake_fps);
Node *EditorSceneImporter::import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags) {
return ResourceImporterScene::get_singleton()->import_scene_from_other_importer(this, p_path, p_flags, p_bake_fps, p_compress_flags);
}
Ref<Animation> EditorSceneImporter::import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
@ -92,7 +92,7 @@ Ref<Animation> EditorSceneImporter::import_animation_from_other_importer(const S
}
void EditorSceneImporter::_bind_methods() {
ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_scene_from_other_importer);
ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps", "compress_flags"), &EditorSceneImporter::import_scene_from_other_importer);
ClassDB::bind_method(D_METHOD("import_animation_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_animation_from_other_importer);
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_import_flags"));
@ -114,7 +114,6 @@ void EditorSceneImporter::_bind_methods() {
BIND_CONSTANT(IMPORT_GENERATE_TANGENT_ARRAYS);
BIND_CONSTANT(IMPORT_FAIL_ON_MISSING_DEPENDENCIES);
BIND_CONSTANT(IMPORT_MATERIALS_IN_INSTANCES);
BIND_CONSTANT(IMPORT_USE_COMPRESSION);
}
/////////////////////////////////
@ -1078,7 +1077,8 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), (meshes_out || materials_out) ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.material),Files (.tres)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_on_reimport"), materials_out));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/octahedral_compression"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/compress", PROPERTY_HINT_FLAGS, "Vertex,Normal,Tangent,Color,TexUV,TexUV2,Bones,Weights,Index"), VS::ARRAY_COMPRESS_DEFAULT >> VS::ARRAY_COMPRESS_BASE));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/storage", PROPERTY_HINT_ENUM, "Built-In,Files (.mesh),Files (.tres)"), meshes_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Enable,Gen Lightmaps", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
@ -1128,7 +1128,7 @@ void ResourceImporterScene::_add_shapes(Node *p_node, const List<Ref<Shape>> &p_
}
}
Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags) {
Ref<EditorSceneImporter> importer;
String ext = p_path.get_extension().to_lower();
@ -1155,7 +1155,7 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte
List<String> missing;
Error err;
return importer->import_scene(p_path, p_flags, p_bake_fps, &missing, &err);
return importer->import_scene(p_path, p_flags, p_bake_fps, p_compress_flags, &missing, &err);
}
Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
@ -1224,10 +1224,10 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
import_flags |= EditorSceneImporter::IMPORT_ANIMATION;
}
if (int(p_options["meshes/compress"])) {
import_flags |= EditorSceneImporter::IMPORT_USE_COMPRESSION;
uint32_t compress_flags = int(p_options["meshes/compress"]) << VS::ARRAY_COMPRESS_BASE;
if (bool(p_options["meshes/octahedral_compression"])) {
compress_flags |= VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION;
}
if (bool(p_options["meshes/ensure_tangents"])) {
import_flags |= EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
}
@ -1246,7 +1246,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
Error err = OK;
List<String> missing_deps; // for now, not much will be done with this
Node *scene = importer->import_scene(src_path, import_flags, fps, &missing_deps, &err);
Node *scene = importer->import_scene(src_path, import_flags, fps, compress_flags, &missing_deps, &err);
if (!scene || err != OK) {
return err;
}
@ -1559,7 +1559,7 @@ uint32_t EditorSceneImporterESCN::get_import_flags() const {
void EditorSceneImporterESCN::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("escn");
}
Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err) {
Error error;
Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error);
ERR_FAIL_COND_V_MSG(!ps.is_valid(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'.");

View file

@ -43,7 +43,7 @@ class EditorSceneImporter : public Reference {
protected:
static void _bind_methods();
Node *import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
Node *import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags);
Ref<Animation> import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
public:
@ -65,7 +65,7 @@ public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
EditorSceneImporter() {}
@ -156,7 +156,7 @@ public:
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
Node *import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
Node *import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags);
Ref<Animation> import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
ResourceImporterScene();
@ -168,7 +168,7 @@ class EditorSceneImporterESCN : public EditorSceneImporter {
public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
};

View file

@ -115,7 +115,7 @@ struct SurfaceData {
Array morphs;
};
MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression) {
MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, uint32_t p_compress_flags) {
mesh_geometry = p_mesh_geometry;
// todo: make this just use a uint64_t FBX ID this is a copy of our original materials unfortunately.
const std::vector<const FBXDocParser::Material *> &material_lookup = model->GetMaterials();
@ -386,7 +386,7 @@ MeshInstance *FBXMeshData::create_fbx_mesh(const ImportState &state, const FBXDo
Mesh::PRIMITIVE_TRIANGLES,
surface->surface_tool->commit_to_arrays(),
surface->morphs,
use_compression ? Mesh::ARRAY_COMPRESS_DEFAULT : Mesh::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION);
p_compress_flags);
if (surface->material.is_valid()) {
mesh->surface_set_name(in_mesh_surface_id, surface->material->get_name());

View file

@ -80,7 +80,7 @@ struct FBXMeshData : Reference {
// translate fbx mesh data from document context to FBX Mesh Geometry Context
bool valid_weight_indexes = false;
MeshInstance *create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, bool use_compression);
MeshInstance *create_fbx_mesh(const ImportState &state, const FBXDocParser::MeshGeometry *p_mesh_geometry, const FBXDocParser::Model *model, uint32_t p_compress_flags);
void gen_weight_info(Ref<SurfaceTool> st, int vertex_id) const;

View file

@ -83,7 +83,7 @@ uint32_t EditorSceneImporterFBX::get_import_flags() const {
return IMPORT_SCENE;
}
Node *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps,
Node *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags,
List<String> *r_missing_deps, Error *r_err) {
// done for performance when re-importing lots of files when testing importer in verbose only!
if (OS::get_singleton()->is_stdout_verbose()) {
@ -188,7 +188,7 @@ Node *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_flag
"For minimal breakage, please export FBX from Blender with -Z forward, and Y up.");
}
Spatial *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, 8, is_blender_fbx);
Spatial *spatial = _generate_scene(p_path, &doc, p_flags, p_bake_fps, p_compress_flags, 8, is_blender_fbx);
// todo: move to document shutdown (will need to be validated after moving; this code has been validated already)
for (FBXDocParser::TokenPtr token : tokens) {
if (token) {
@ -364,6 +364,7 @@ Spatial *EditorSceneImporterFBX::_generate_scene(
const FBXDocParser::Document *p_document,
const uint32_t p_flags,
int p_bake_fps,
const uint32_t p_compress_flags,
const int32_t p_max_bone_weights,
bool p_is_blender_fbx) {
ImportState state;
@ -664,7 +665,7 @@ Spatial *EditorSceneImporterFBX::_generate_scene(
mesh_data_precached->mesh_node = fbx_node;
// mesh node, mesh id
mesh_node = mesh_data_precached->create_fbx_mesh(state, mesh_geometry, fbx_node->fbx_model, (p_flags & IMPORT_USE_COMPRESSION) != 0);
mesh_node = mesh_data_precached->create_fbx_mesh(state, mesh_geometry, fbx_node->fbx_model, p_compress_flags);
if (!state.MeshNodes.has(mesh_id)) {
state.MeshNodes.insert(mesh_id, fbx_node);
}

View file

@ -115,6 +115,7 @@ private:
Spatial *_generate_scene(const String &p_path, const FBXDocParser::Document *p_document,
const uint32_t p_flags,
int p_bake_fps,
const uint32_t p_compress_flags,
const int32_t p_max_bone_weights,
bool p_is_blender_fbx);
@ -128,7 +129,7 @@ public:
virtual void get_extensions(List<String> *r_extensions) const;
virtual uint32_t get_import_flags() const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags, List<String> *r_missing_deps, Error *r_err = nullptr);
void create_mesh_data_skin(ImportState &state, const Ref<FBXNode> &fbx_node, uint64_t mesh_id);
};

View file

@ -21,7 +21,8 @@
<argument index="0" name="path" type="String" />
<argument index="1" name="flags" type="int" default="0" />
<argument index="2" name="bake_fps" type="float" default="1000.0" />
<argument index="3" name="state" type="GLTFState" default="null" />
<argument index="3" name="compress_flags" type="int" default="2194432" />
<argument index="4" name="state" type="GLTFState" default="null" />
<description>
</description>
</method>
@ -30,7 +31,8 @@
<argument index="0" name="path" type="String" />
<argument index="1" name="flags" type="int" default="0" />
<argument index="2" name="bake_fps" type="float" default="1000.0" />
<argument index="3" name="state" type="GLTFState" default="null" />
<argument index="3" name="compress_flags" type="int" default="2194432" />
<argument index="4" name="state" type="GLTFState" default="null" />
<description>
</description>
</method>

View file

@ -56,12 +56,12 @@ void EditorSceneImporterGLTF::get_extensions(List<String> *r_extensions) const {
}
Node *EditorSceneImporterGLTF::import_scene(const String &p_path,
uint32_t p_flags, int p_bake_fps,
uint32_t p_flags, int p_bake_fps, uint32_t p_compress_flags,
List<String> *r_missing_deps,
Error *r_err) {
Ref<PackedSceneGLTF> importer;
importer.instance();
return importer->import_scene(p_path, p_flags, p_bake_fps, r_missing_deps, r_err, Ref<GLTFState>());
return importer->import_scene(p_path, p_flags, p_bake_fps, p_compress_flags, r_missing_deps, r_err, Ref<GLTFState>());
}
Ref<Animation> EditorSceneImporterGLTF::import_animation(const String &p_path,
@ -74,19 +74,19 @@ void PackedSceneGLTF::_bind_methods() {
ClassDB::bind_method(
D_METHOD("export_gltf", "node", "path", "flags", "bake_fps"),
&PackedSceneGLTF::export_gltf, DEFVAL(0), DEFVAL(1000.0f));
ClassDB::bind_method(D_METHOD("pack_gltf", "path", "flags", "bake_fps", "state"),
&PackedSceneGLTF::pack_gltf, DEFVAL(0), DEFVAL(1000.0f), DEFVAL(Ref<GLTFState>()));
ClassDB::bind_method(D_METHOD("import_gltf_scene", "path", "flags", "bake_fps", "state"),
&PackedSceneGLTF::import_gltf_scene, DEFVAL(0), DEFVAL(1000.0f), DEFVAL(Ref<GLTFState>()));
ClassDB::bind_method(D_METHOD("pack_gltf", "path", "flags", "bake_fps", "compress_flags", "state"),
&PackedSceneGLTF::pack_gltf, DEFVAL(0), DEFVAL(1000.0f), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT), DEFVAL(Ref<GLTFState>()));
ClassDB::bind_method(D_METHOD("import_gltf_scene", "path", "flags", "bake_fps", "compress_flags", "state"),
&PackedSceneGLTF::import_gltf_scene, DEFVAL(0), DEFVAL(1000.0f), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT), DEFVAL(Ref<GLTFState>()));
}
Node *PackedSceneGLTF::import_gltf_scene(const String &p_path, uint32_t p_flags, float p_bake_fps, Ref<GLTFState> r_state) {
Node *PackedSceneGLTF::import_gltf_scene(const String &p_path, uint32_t p_flags, float p_bake_fps, uint32_t p_compress_flags, Ref<GLTFState> r_state) {
Error err = FAILED;
List<String> deps;
return import_scene(p_path, p_flags, p_bake_fps, &deps, &err, r_state);
return import_scene(p_path, p_flags, p_bake_fps, p_compress_flags, &deps, &err, r_state);
}
Node *PackedSceneGLTF::import_scene(const String &p_path, uint32_t p_flags,
int p_bake_fps,
int p_bake_fps, uint32_t p_compress_flags,
List<String> *r_missing_deps,
Error *r_err,
Ref<GLTFState> r_state) {
@ -97,6 +97,7 @@ Node *PackedSceneGLTF::import_scene(const String &p_path, uint32_t p_flags,
p_flags & EditorSceneImporter::IMPORT_USE_NAMED_SKIN_BINDS;
r_state->use_legacy_names =
p_flags & EditorSceneImporter::IMPORT_USE_LEGACY_NAMES;
r_state->compress_flags = p_compress_flags;
Ref<GLTFDocument> gltf_document;
gltf_document.instance();
@ -127,10 +128,10 @@ Node *PackedSceneGLTF::import_scene(const String &p_path, uint32_t p_flags,
}
void PackedSceneGLTF::pack_gltf(String p_path, int32_t p_flags,
real_t p_bake_fps, Ref<GLTFState> r_state) {
real_t p_bake_fps, uint32_t p_compress_flags, Ref<GLTFState> r_state) {
Error err = FAILED;
List<String> deps;
Node *root = import_scene(p_path, p_flags, p_bake_fps, &deps, &err, r_state);
Node *root = import_scene(p_path, p_flags, p_bake_fps, p_compress_flags, &deps, &err, r_state);
ERR_FAIL_COND(err != OK);
pack(root);
}

View file

@ -63,7 +63,7 @@ public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags,
int p_bake_fps,
int p_bake_fps, uint32_t p_compress_flags,
List<String> *r_missing_deps = NULL,
Error *r_err = NULL);
virtual Ref<Animation> import_animation(const String &p_path,
@ -85,12 +85,12 @@ public:
virtual Error export_gltf(Node *p_root, String p_path, int32_t p_flags = 0,
real_t p_bake_fps = 1000.0f);
virtual Node *import_scene(const String &p_path, uint32_t p_flags,
int p_bake_fps,
int p_bake_fps, uint32_t p_compress_flags,
List<String> *r_missing_deps,
Error *r_err,
Ref<GLTFState> r_state);
virtual Node *import_gltf_scene(const String &p_path, uint32_t p_flags, float p_bake_fps, Ref<GLTFState> r_state = Ref<GLTFState>());
virtual Node *import_gltf_scene(const String &p_path, uint32_t p_flags, float p_bake_fps, uint32_t p_compress_flags, Ref<GLTFState> r_state = Ref<GLTFState>());
virtual void pack_gltf(String p_path, int32_t p_flags = 0,
real_t p_bake_fps = 1000.0f, Ref<GLTFState> r_state = Ref<GLTFState>());
real_t p_bake_fps = 1000.0f, uint32_t p_compress_flags = Mesh::ARRAY_COMPRESS_DEFAULT, Ref<GLTFState> r_state = Ref<GLTFState>());
};
#endif // EDITOR_SCENE_IMPORTER_GLTF_H

View file

@ -2870,7 +2870,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
mat = mat3d;
}
int32_t mat_idx = import_mesh->get_surface_count();
import_mesh->add_surface_from_arrays(primitive, array, morphs);
import_mesh->add_surface_from_arrays(primitive, array, morphs, state->compress_flags);
import_mesh->surface_set_material(mat_idx, mat);
}

View file

@ -66,6 +66,7 @@ class GLTFState : public Resource {
bool use_named_skin_binds = false;
bool use_legacy_names = false;
uint32_t compress_flags = 0;
Vector<Ref<GLTFNode>> nodes;
Vector<Vector<uint8_t>> buffers;