diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 1c57d374b20d..9607ee9876bd 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -99,9 +99,10 @@ #include "plugins/color_ramp_editor_plugin.h" #include "plugins/collision_shape_2d_editor_plugin.h" #include "plugins/gi_probe_editor_plugin.h" -#include "import/resource_import_texture.h" +#include "import/resource_importer_texture.h" #include "import/resource_importer_csv_translation.h" -#include "import/resource_import_wav.h" +#include "import/resource_importer_wav.h" +#include "import/resource_importer_obj.h" // end #include "editor_settings.h" #include "io_plugins/editor_texture_import_plugin.h" @@ -5131,6 +5132,11 @@ EditorNode::EditorNode() { import_wav.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_wav); + + Ref import_obj; + import_obj.instance(); + ResourceFormatImporter::get_singleton()->add_importer(import_obj); + } _pvrtc_register_compressors(); diff --git a/tools/editor/import/resource_importer_obj.cpp b/tools/editor/import/resource_importer_obj.cpp new file mode 100644 index 000000000000..e6e23366f68e --- /dev/null +++ b/tools/editor/import/resource_importer_obj.cpp @@ -0,0 +1,231 @@ +#include "resource_importer_obj.h" + +#include "io/resource_saver.h" +#include "scene/resources/mesh.h" +#include "scene/resources/surface_tool.h" +#include "scene/resources/surface_tool.h" +#include "os/file_access.h" + +String ResourceImporterOBJ::get_importer_name() const { + + return "obj_mesh"; +} + +String ResourceImporterOBJ::get_visible_name() const{ + + return "OBJ As Mesh"; +} +void ResourceImporterOBJ::get_recognized_extensions(List *p_extensions) const{ + + p_extensions->push_back("obj"); +} +String ResourceImporterOBJ::get_save_extension() const { + return "msh"; +} + +String ResourceImporterOBJ::get_resource_type() const{ + + return "Mesh"; +} + +bool ResourceImporterOBJ::get_option_visibility(const String& p_option,const Map& p_options) const { + + return true; +} + +int ResourceImporterOBJ::get_preset_count() const { + return 0; +} +String ResourceImporterOBJ::get_preset_name(int p_idx) const { + + return String(); +} + + +void ResourceImporterOBJ::get_import_options(List *r_options,int p_preset) const { + + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"generate/tangents"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"generate/normals"),true)); + //not for nowp + //r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"import/materials"))); + //r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"import/textures"))); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"force/flip_faces"),false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"force/smooth_shading"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"force/weld_vertices"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"force/weld_tolerance",PROPERTY_HINT_RANGE,"0.00001,16,0.00001"),0.0001)); + //r_options->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192")); + +} + + + +Error ResourceImporterOBJ::import(const String& p_source_file, const String& p_save_path, const Map& p_options, List* r_platform_variants, List *r_gen_files) { + + FileAccessRef f = FileAccess::open(p_source_file,FileAccess::READ); + ERR_FAIL_COND_V(!f,ERR_CANT_OPEN); + + Ref mesh = Ref( memnew( Mesh ) ); + Map > name_map; + + + + bool generate_normals=p_options["generate/normals"]; + bool generate_tangents=p_options["generate/tangents"]; + bool flip_faces=p_options["force/flip_faces"]; + bool force_smooth=p_options["force/smooth_shading"]; + bool weld_vertices=p_options["force/weld_vertices"]; + float weld_tolerance=p_options["force/weld_tolerance"]; + Vector vertices; + Vector normals; + Vector uvs; + String name; + + Ref surf_tool = memnew( SurfaceTool) ; + surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); + if (force_smooth) + surf_tool->add_smooth_group(true); + int has_index_data=false; + + while(true) { + + + String l = f->get_line().strip_edges(); + + if (l.begins_with("v ")) { + //vertex + Vector v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); + Vector3 vtx; + vtx.x=v[1].to_float(); + vtx.y=v[2].to_float(); + vtx.z=v[3].to_float(); + vertices.push_back(vtx); + } else if (l.begins_with("vt ")) { + //uv + Vector v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<3,ERR_INVALID_DATA); + Vector2 uv; + uv.x=v[1].to_float(); + uv.y=1.0-v[2].to_float(); + uvs.push_back(uv); + + } else if (l.begins_with("vn ")) { + //normal + Vector v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); + Vector3 nrm; + nrm.x=v[1].to_float(); + nrm.y=v[2].to_float(); + nrm.z=v[3].to_float(); + normals.push_back(nrm); + } if (l.begins_with("f ")) { + //vertex + + has_index_data=true; + Vector v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); + + //not very fast, could be sped up + + + Vector face[3]; + face[0] = v[1].split("/"); + face[1] = v[2].split("/"); + ERR_FAIL_COND_V(face[0].size()==0,ERR_PARSE_ERROR); + ERR_FAIL_COND_V(face[0].size()!=face[1].size(),ERR_PARSE_ERROR); + for(int i=2;iadd_normal(normals[norm]); + } + + if (face[idx].size()>=2 && face[idx][1]!=String()) { + + int uv = face[idx][1].to_int()-1; + ERR_FAIL_INDEX_V(uv,uvs.size(),ERR_PARSE_ERROR); + surf_tool->add_uv(uvs[uv]); + } + + int vtx = face[idx][0].to_int()-1; + ERR_FAIL_INDEX_V(vtx,vertices.size(),ERR_PARSE_ERROR); + + Vector3 vertex = vertices[vtx]; + if (weld_vertices) + vertex=vertex.snapped(weld_tolerance); + surf_tool->add_vertex(vertex); + } + + face[1]=face[2]; + } + } else if (l.begins_with("s ") && !force_smooth) { //smoothing + String what = l.substr(2,l.length()).strip_edges(); + if (what=="off") + surf_tool->add_smooth_group(false); + else + surf_tool->add_smooth_group(true); + + } else if (l.begins_with("o ") || f->eof_reached()) { //new surface or done + + if (has_index_data) { + //new object/surface + if (generate_normals || force_smooth) + surf_tool->generate_normals(); + if (uvs.size() && (normals.size() || generate_normals) && generate_tangents) + surf_tool->generate_tangents(); + + surf_tool->index(); + mesh = surf_tool->commit(mesh); + if (name=="") + name=vformat(TTR("Surface %d"),mesh->get_surface_count()-1); + mesh->surface_set_name(mesh->get_surface_count()-1,name); + name=""; + surf_tool->clear(); + surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); + if (force_smooth) + surf_tool->add_smooth_group(true); + + has_index_data=false; + + if (f->eof_reached()) + break; + } + + if (l.begins_with("o ")) //name + name=l.substr(2,l.length()).strip_edges(); + } + } + +/* + TODO, check existing materials and merge? + //re-apply materials if exist + for(int i=0;iget_surface_count();i++) { + + String n = mesh->surface_get_name(i); + if (name_map.has(n)) + mesh->surface_set_material(i,name_map[n]); + } +*/ + + Error err = ResourceSaver::save(p_save_path+".msh",mesh); + + return err; + +} + +ResourceImporterOBJ::ResourceImporterOBJ() +{ + +} diff --git a/tools/editor/import/resource_importer_obj.h b/tools/editor/import/resource_importer_obj.h new file mode 100644 index 000000000000..d2a3c4fddddf --- /dev/null +++ b/tools/editor/import/resource_importer_obj.h @@ -0,0 +1,28 @@ +#ifndef RESOURCEIMPORTEROBJ_H +#define RESOURCEIMPORTEROBJ_H + + +#include "io/resource_import.h" + +class ResourceImporterOBJ : public ResourceImporter { + GDCLASS(ResourceImporterOBJ,ResourceImporter) +public: + virtual String get_importer_name() const; + virtual String get_visible_name() const; + virtual void get_recognized_extensions(List *p_extensions) const; + virtual String get_save_extension() const; + virtual String get_resource_type() const; + + virtual int get_preset_count() const; + virtual String get_preset_name(int p_idx) const; + + virtual void get_import_options(List *r_options,int p_preset=0) const; + virtual bool get_option_visibility(const String& p_option,const Map& p_options) const; + + virtual Error import(const String& p_source_file,const String& p_save_path,const Map& p_options,List* r_platform_variants,List* r_gen_files=NULL); + + ResourceImporterOBJ(); +}; + + +#endif // RESOURCEIMPORTEROBJ_H diff --git a/tools/editor/import/resource_import_texture.cpp b/tools/editor/import/resource_importer_texture.cpp similarity index 99% rename from tools/editor/import/resource_import_texture.cpp rename to tools/editor/import/resource_importer_texture.cpp index 940b932e5477..3cbe034e4de6 100644 --- a/tools/editor/import/resource_import_texture.cpp +++ b/tools/editor/import/resource_importer_texture.cpp @@ -1,4 +1,4 @@ -#include "resource_import_texture.h" +#include "resource_importer_texture.h" #include "io/image_loader.h" #include "scene/resources/texture.h" diff --git a/tools/editor/import/resource_import_texture.h b/tools/editor/import/resource_importer_texture.h similarity index 100% rename from tools/editor/import/resource_import_texture.h rename to tools/editor/import/resource_importer_texture.h diff --git a/tools/editor/import/resource_import_wav.cpp b/tools/editor/import/resource_importer_wav.cpp similarity index 99% rename from tools/editor/import/resource_import_wav.cpp rename to tools/editor/import/resource_importer_wav.cpp index c277bd3b6c76..ee53b740cad0 100644 --- a/tools/editor/import/resource_import_wav.cpp +++ b/tools/editor/import/resource_importer_wav.cpp @@ -1,4 +1,4 @@ -#include "resource_import_wav.h" +#include "resource_importer_wav.h" #include "scene/resources/audio_stream_sample.h" #include "os/file_access.h" diff --git a/tools/editor/import/resource_import_wav.h b/tools/editor/import/resource_importer_wav.h similarity index 100% rename from tools/editor/import/resource_import_wav.h rename to tools/editor/import/resource_importer_wav.h