예제 #1
0
void MonoBuildTab::_load_issues_from_file(const String &p_csv_file) {

	FileAccessRef f = FileAccess::open(p_csv_file, FileAccess::READ);

	if (!f)
		return;

	while (!f->eof_reached()) {
		Vector<String> csv_line = f->get_csv_line();

		if (csv_line.size() == 1 && csv_line[0].empty())
			return;

		ERR_CONTINUE(csv_line.size() != 7);

		BuildIssue issue;
		issue.warning = csv_line[0] == "warning";
		issue.file = csv_line[1];
		issue.line = csv_line[2].to_int();
		issue.column = csv_line[3].to_int();
		issue.code = csv_line[4];
		issue.message = csv_line[5];
		issue.project_file = csv_line[6];

		if (issue.warning)
			warning_count += 1;
		else
			error_count += 1;

		issues.push_back(issue);
	}
}
예제 #2
0
void EditorFileSystem::_save_late_updated_files() {
	//files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file
	String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update2");
	FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE);
	for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) {
		f->store_line(E->get());
	}
}
Error EditorTranslationImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) {

	Ref<ResourceImportMetadata> from = p_from;
	ERR_FAIL_COND_V( from->get_source_count()!=1, ERR_INVALID_PARAMETER);

	String source = EditorImportPlugin::expand_source_path( from->get_source_path(0) );

	FileAccessRef f = FileAccess::open(source,FileAccess::READ);

	ERR_FAIL_COND_V( !f, ERR_INVALID_PARAMETER );

	bool first=false;
	bool skip_first = from->get_option("skip_first");
	int index = from->get_option("index");
	index+=1;
	String locale = from->get_option("locale");

	Ref<Translation> translation = memnew( Translation );

	translation->set_locale( locale );

	Vector<String> line = f->get_csv_line();

	while(line.size()>1) {


		if (!skip_first) {
			ERR_FAIL_INDEX_V(index,line.size(),ERR_INVALID_DATA );
			translation->add_message(line[0].strip_edges(),line[index]);

		} else {

			skip_first=false;
		}

		line = f->get_csv_line();
	}

	from->set_source_md5(0,FileAccess::get_md5(source));
	from->set_editor(get_name());

	String dst_path = p_path;

	if (from->get_option("compress")) {

		Ref<PHashTranslation> cxl = memnew( PHashTranslation );
		cxl->generate( translation );
		translation=cxl;
	}

	translation->set_import_metadata(from);
	return ResourceSaver::save(dst_path,translation);

}
예제 #4
0
bool GodotSharpExport::_add_file(const String &p_src_path, const String &p_dst_path, bool p_remap) {

	FileAccessRef f = FileAccess::open(p_src_path, FileAccess::READ);
	ERR_FAIL_COND_V(!f, false);

	Vector<uint8_t> data;
	data.resize(f->get_len());
	f->get_buffer(data.ptrw(), data.size());

	add_file(p_dst_path, data, p_remap);

	return true;
}
예제 #5
0
파일: power_x11.cpp 프로젝트: 93i/godot
bool PowerX11::read_power_file(const char *base, const char *node, const char *key, char *buf, size_t buflen) {
	ssize_t br = 0;
	FileAccessRef fd = open_power_file(base, node, key);
	if (!fd) {
		return false;
	}
	br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), buflen - 1);
	fd->close();
	if (br < 0) {
		return false;
	}
	buf[br] = '\0'; // null-terminate the string
	return true;
}
예제 #6
0
static Error save_file(const String &p_path, const List<String> &p_content) {

	FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);

	ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);

	for (const List<String>::Element *e = p_content.front(); e != NULL; e = e->next()) {
		file->store_string(e->get());
	}

	file->close();

	return OK;
}
예제 #7
0
Error NETSolution::save() {
	bool dir_exists = DirAccess::exists(path);
	ERR_EXPLAIN("The directory does not exist.");
	ERR_FAIL_COND_V(!dir_exists, ERR_FILE_BAD_PATH);

	String projs_decl;
	String sln_platform_cfg;
	String proj_platform_cfg;

	for (Map<String, ProjectInfo>::Element *E = projects.front(); E; E = E->next()) {
		const String &name = E->key();
		const ProjectInfo &procinfo = E->value();

		projs_decl += sformat(PROJECT_DECLARATION, name, name + ".csproj", procinfo.guid);

		for (int i = 0; i < procinfo.configs.size(); i++) {
			const String &config = procinfo.configs[i];

			if (i != 0) {
				sln_platform_cfg += "\n";
				proj_platform_cfg += "\n";
			}

			sln_platform_cfg += sformat(SOLUTION_PLATFORMS_CONFIG, config);
			proj_platform_cfg += sformat(PROJECT_PLATFORMS_CONFIG, procinfo.guid, config);
		}
	}

	String content = sformat(SOLUTION_TEMPLATE, projs_decl, sln_platform_cfg, proj_platform_cfg);

	FileAccessRef file = FileAccess::open(path_join(path, name + ".sln"), FileAccess::WRITE);
	ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
	file->store_string(content);
	file->close();

	return OK;
}
Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) {


	Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path);

	if (rimd.is_null()) {

		StringName group = EditorImportExport::get_singleton()->image_get_export_group(p_path);

		if (group!=StringName()) {
			//handled by export group
			rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) );

			int group_format=0;
			float group_lossy_quality=EditorImportExport::get_singleton()->image_export_group_get_lossy_quality(group);
			int group_shrink=EditorImportExport::get_singleton()->image_export_group_get_shrink(group);
			group_shrink*=EditorImportExport::get_singleton()->get_export_image_shrink();

			switch(EditorImportExport::get_singleton()->image_export_group_get_image_action(group)) {
				case EditorImportExport::IMAGE_ACTION_NONE: {

					switch(EditorImportExport::get_singleton()->get_export_image_action()) {
						case EditorImportExport::IMAGE_ACTION_NONE: {

							group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS; //?

						} break; //use default
						case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: {
							group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY;
						} break; //use default
						case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: {
							group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM;
						} break; //use default
					}

					group_lossy_quality=EditorImportExport::get_singleton()->get_export_image_quality();

				} break; //use default
				case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: {
					group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY;
				} break; //use default
				case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: {
					group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM;
				} break; //use default
			}


			int flags=0;

			if (Globals::get_singleton()->get("texture_import/filter"))
				flags|=IMAGE_FLAG_FILTER;
			if (!Globals::get_singleton()->get("texture_import/gen_mipmaps"))
				flags|=IMAGE_FLAG_NO_MIPMAPS;
			if (!Globals::get_singleton()->get("texture_import/repeat"))
				flags|=IMAGE_FLAG_REPEAT;

			flags|=IMAGE_FLAG_FIX_BORDER_ALPHA;

			print_line("group format"+itos(group_format));
			rimd->set_option("format",group_format);
			rimd->set_option("flags",flags);
			rimd->set_option("quality",group_lossy_quality);
			rimd->set_option("atlas",false);
			rimd->set_option("shrink",group_shrink);
			rimd->add_source(EditorImportPlugin::validate_source_path(p_path));

		} else if (EditorImportExport::get_singleton()->get_image_formats().has(p_path.extension().to_lower()) && EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE) {
			//handled by general image export settings

			rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) );

			switch(EditorImportExport::get_singleton()->get_export_image_action()) {
				case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_DISK_LOSSY); break;
				case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_RAM); break;
			}

			int flags=0;

			if (Globals::get_singleton()->get("texture_import/filter"))
				flags|=IMAGE_FLAG_FILTER;
			if (!Globals::get_singleton()->get("texture_import/gen_mipmaps"))
				flags|=IMAGE_FLAG_NO_MIPMAPS;
			if (!Globals::get_singleton()->get("texture_import/repeat"))
				flags|=IMAGE_FLAG_REPEAT;

			flags|=IMAGE_FLAG_FIX_BORDER_ALPHA;

			rimd->set_option("shrink",EditorImportExport::get_singleton()->get_export_image_shrink());
			rimd->set_option("flags",flags);
			rimd->set_option("quality",EditorImportExport::get_singleton()->get_export_image_quality());
			rimd->set_option("atlas",false);
			rimd->add_source(EditorImportPlugin::validate_source_path(p_path));

		} else {
			return Vector<uint8_t>();
		}
	}

	int fmt = rimd->get_option("format");

	if (fmt!=IMAGE_FORMAT_COMPRESS_RAM && fmt!=IMAGE_FORMAT_COMPRESS_DISK_LOSSY)  {
		print_line("no compress ram or lossy");
		return Vector<uint8_t>(); //pointless to do anything, since no need to reconvert
	}

	uint32_t flags = rimd->get_option("flags");
	uint8_t shrink = rimd->has_option("shrink") ? rimd->get_option("shrink"): Variant(1);
	uint8_t format = rimd->get_option("format");
	uint8_t comp = (format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM)?uint8_t(p_platform->get_image_compression()):uint8_t(255);

	MD5_CTX ctx;
	uint8_t f4[4];
	encode_uint32(flags,&f4[0]);
	MD5Init(&ctx);
	String gp = Globals::get_singleton()->globalize_path(p_path);
	CharString cs = gp.utf8();
	MD5Update(&ctx,(unsigned char*)cs.get_data(),cs.length());
	MD5Update(&ctx,f4,4);
	MD5Update(&ctx,&format,1);
	MD5Update(&ctx,&comp,1);
	MD5Update(&ctx,&shrink,1);
	MD5Final(&ctx);

	uint64_t sd=0;
	String smd5;

	String md5 = String::md5(ctx.digest);

	String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/");

	bool valid=false;
	{
		//if existing, make sure it's valid
		FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::READ);
		if (f) {

			uint64_t d = f->get_line().strip_edges().to_int64();
			sd = FileAccess::get_modified_time(p_path);

			if (d==sd) {
				valid=true;
			} else {
				String cmd5 = f->get_line().strip_edges();
				smd5 = FileAccess::get_md5(p_path);
				if (cmd5==smd5) {
					valid=true;
				}
			}


		}
	}

	if (!valid) {
		//cache failed, convert
		Error err = import2(tmp_path+"imgexp-"+md5+".tex",rimd,p_platform->get_image_compression(),true);
		ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>());
		FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::WRITE);

		if (sd==0)
			sd = FileAccess::get_modified_time(p_path);
		if (smd5==String())
			smd5 = FileAccess::get_md5(p_path);

		f->store_line(String::num(sd));
		f->store_line(smd5);
		f->store_line(gp); //source path for reference
	}


	Vector<uint8_t> ret;
	FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".tex",FileAccess::READ);
	ERR_FAIL_COND_V(!f,ret);

	ret.resize(f->get_len());
	f->get_buffer(ret.ptr(),ret.size());

	return ret;
}
예제 #9
0
void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) {

	String fpath =  EditorSettings::get_singleton()->get_settings_path().plus_file("tmp_bar-settings.xml");
	{
		FileAccessRef f = FileAccess::open(fpath,FileAccess::WRITE);
		f->store_buffer(p_descriptor.ptr(),p_descriptor.size());
	}

	Ref<XMLParser> parser = memnew( XMLParser );
	Error err = parser->open(fpath);
	ERR_FAIL_COND(err!=OK);

	String txt;
	err = parser->read();
	Vector<String> depth;

	while(err!=ERR_FILE_EOF) {

		ERR_FAIL_COND(err!=OK);

		switch(parser->get_node_type()) {

			case XMLParser::NODE_NONE: {
				print_line("???");
			} break;
			case XMLParser::NODE_ELEMENT: {
				String e="<";
				e+=parser->get_node_name();
				for(int i=0;i<parser->get_attribute_count();i++) {
					e+=" ";
					e+=parser->get_attribute_name(i)+"=\"";
					e+=parser->get_attribute_value(i)+"\" ";
				}



				if (parser->is_empty()) {
					e+="/";
				} else {
					depth.push_back(parser->get_node_name());
				}

				e+=">";
				txt+=e;

			} break;
			case XMLParser::NODE_ELEMENT_END: {

				txt+="</"+parser->get_node_name()+">";
				if (depth.size() && depth[depth.size()-1]==parser->get_node_name()) {
					depth.resize(depth.size()-1);
				}


			} break;
			case XMLParser::NODE_TEXT: {
				if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="id") {

					txt+=package;
				} else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="name") {

					String aname;
					if (this->name!="") {
						aname=this->name;
					} else {
						aname = GlobalConfig::get_singleton()->get("application/name");

					}

					if (aname=="") {
						aname=_MKSTR(VERSION_NAME);
					}

					txt+=aname;

				} else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="versionNumber") {
					txt+=itos(version_code);
				} else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="description") {
					txt+=description;
				} else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="author") {
					txt+=author_name;
				} else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="authorId") {
					txt+=author_id;
				} else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="category") {
					txt+=category;
				} else {
					txt+=parser->get_node_data();
				}
			} break;
			case XMLParser::NODE_COMMENT: {
				txt+="<!--"+parser->get_node_name()+"-->";
			} break;
			case XMLParser::NODE_CDATA: {
				//ignore
				//print_line("cdata");
			} break;
			case XMLParser::NODE_UNKNOWN: {
				//ignore
				txt+="<"+parser->get_node_name()+">";
			} break;
		}

		err = parser->read();
	}


	CharString cs = txt.utf8();
	p_descriptor.resize(cs.length());
	for(int i=0;i<cs.length();i++)
		p_descriptor[i]=cs[i];

}
예제 #10
0
Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, int p_flags) {


	EditorProgress ep("export","Exporting for BlackBerry 10",104);

	String src_template=custom_package;

	if (src_template=="") {
		String err;
		src_template = find_export_template("bb10.zip", &err);
		if (src_template=="") {
			EditorNode::add_io_error(err);
			return ERR_FILE_NOT_FOUND;
		}
	}

	FileAccess *src_f=NULL;
	zlib_filefunc_def io = zipio_create_io_from_file(&src_f);

	ep.step("Creating FileSystem for BAR",0);

	unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io);
	if (!pkg) {

		EditorNode::add_io_error("Could not find template zip to export:\n"+src_template);
		return ERR_FILE_NOT_FOUND;
	}

	DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
	da->change_dir(EditorSettings::get_singleton()->get_settings_path());


	if (da->change_dir("tmp")!=OK) {
		da->make_dir("tmp");
		if (da->change_dir("tmp")!=OK)
			return ERR_CANT_CREATE;
	}

	if (da->change_dir("bb10_export")!=OK) {
		da->make_dir("bb10_export");
		if (da->change_dir("bb10_export")!=OK) {
			return ERR_CANT_CREATE;
		}
	}


	String bar_dir = da->get_current_dir();
	if (bar_dir.ends_with("/")) {
		bar_dir=bar_dir.substr(0,bar_dir.length()-1);
	}

	//THIS IS SUPER, SUPER DANGEROUS!!!!
	//CAREFUL WITH THIS CODE, MIGHT DELETE USERS HARD DRIVE OR HOME DIR
	//EXTRA CHECKS ARE IN PLACE EVERYWERE TO MAKE SURE NOTHING BAD HAPPENS BUT STILL....
	//BE SUPER CAREFUL WITH THIS PLEASE!!!
	//BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!!

	bool berr = bar_dir.ends_with("bb10_export");
	if (berr) {
		if (da->list_dir_begin()) {
			EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
			ERR_FAIL_COND_V(berr,FAILED);
		};

		String f = da->get_next();
		while (f != "") {

			if (f == "." || f == "..") {
				f = da->get_next();
				continue;
			};
			Error err = da->remove(bar_dir + "/" + f);
			if (err != OK) {
				EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
				ERR_FAIL_COND_V(err!=OK,err);
			};
			f = da->get_next();
		};

		da->list_dir_end();

	} else {
		print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!");
		ERR_FAIL_V(ERR_OMFG_THIS_IS_VERY_VERY_BAD);
	}


	ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
	int ret = unzGoToFirstFile(pkg);



	while(ret==UNZ_OK) {

		//get filename
		unz_file_info info;
		char fname[16384];
		ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);

		String file=fname;

		Vector<uint8_t> data;
		data.resize(info.uncompressed_size);

		//read
		unzOpenCurrentFile(pkg);
		unzReadCurrentFile(pkg,data.ptr(),data.size());
		unzCloseCurrentFile(pkg);

		//write

		if (file=="bar-descriptor.xml") {

			_fix_descriptor(data);
		}

		if (file=="icon.png") {
			bool found=false;

			if (this->icon!="" && this->icon.ends_with(".png")) {

				FileAccess *f = FileAccess::open(this->icon,FileAccess::READ);
				if (f) {

					data.resize(f->get_len());
					f->get_buffer(data.ptr(),data.size());
					memdelete(f);
					found=true;
				}

			}

			if (!found) {

				String appicon = GlobalConfig::get_singleton()->get("application/icon");
				if (appicon!="" && appicon.ends_with(".png")) {
					FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
					if (f) {
						data.resize(f->get_len());
						f->get_buffer(data.ptr(),data.size());
						memdelete(f);
					}
				}
			}
		}


		if (file.find("/")) {

			da->make_dir_recursive(file.get_base_dir());
		}

		FileAccessRef wf = FileAccess::open(bar_dir.plus_file(file),FileAccess::WRITE);
		wf->store_buffer(data.ptr(),data.size());

		ret = unzGoToNextFile(pkg);
	}

	ep.step("Adding Files..",2);

	FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE);
	if (!dst) {
		EditorNode::add_io_error("Can't copy executable file to:\n "+p_path);
		return ERR_FILE_CANT_WRITE;
	}
	save_pack(dst, false, 1024);
	dst->close();
	memdelete(dst);

	ep.step("Creating BAR Package..",104);

	String bb_packager=EditorSettings::get_singleton()->get("blackberry/host_tools");
	bb_packager=bb_packager.plus_file("blackberry-nativepackager");
	if (OS::get_singleton()->get_name()=="Windows")
		bb_packager+=".bat";


	if (!FileAccess::exists(bb_packager)) {
		EditorNode::add_io_error("Can't find packager:\n"+bb_packager);
		return ERR_CANT_OPEN;
	}

	List<String> args;
	args.push_back("-package");
	args.push_back(p_path);
	if (p_debug) {

		String debug_token=EditorSettings::get_singleton()->get("blackberry/debug_token");
		if (!FileAccess::exists(debug_token)) {
			EditorNode::add_io_error("Debug token not found!");
		} else {
			args.push_back("-debugToken");
			args.push_back(debug_token);
		}
		args.push_back("-devMode");
		args.push_back("-configuration");
		args.push_back("Device-Debug");
	} else {

		args.push_back("-configuration");
		args.push_back("Device-Release");
	}
	args.push_back(bar_dir.plus_file("bar-descriptor.xml"));

	int ec;

	Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec);

	if (err!=OK)
		return err;
	if (ec!=0)
		return ERR_CANT_CREATE;

	return OK;

}
예제 #11
0
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) {

	FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);
	ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);

	Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
	Map<String, Ref<Material> > 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<Vector3> vertices;
	Vector<Vector3> normals;
	Vector<Vector2> uvs;
	String name;

	Ref<SurfaceTool> 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<String> 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<String> 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<String> 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);
		} else if (l.begins_with("f ")) {
			//vertex

			has_index_data = true;
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);

			//not very fast, could be sped up

			Vector<String> 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; i < v.size() - 1; i++) {

				face[2] = v[i + 1].split("/");
				ERR_FAIL_COND_V(face[0].size() != face[2].size(), ERR_PARSE_ERROR);
				for (int j = 0; j < 3; j++) {

					int idx = j;

					if (!flip_faces && idx < 2) {
						idx = 1 ^ idx;
					}

					if (face[idx].size() == 3) {
						int norm = face[idx][2].to_int() - 1;
						if (norm < 0)
							norm += normals.size() + 1;
						ERR_FAIL_INDEX_V(norm, normals.size(), ERR_PARSE_ERROR);
						surf_tool->add_normal(normals[norm]);
					}

					if (face[idx].size() >= 2 && face[idx][1] != String()) {
						int uv = face[idx][1].to_int() - 1;
						if (uv < 0)
							uv += uvs.size() + 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;
					if (vtx < 0)
						vtx += vertices.size() + 1;
					ERR_FAIL_INDEX_V(vtx, vertices.size(), ERR_PARSE_ERROR);

					Vector3 vertex = vertices[vtx];
					if (weld_vertices)
						vertex.snap(Vector3(weld_tolerance, weld_tolerance, 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;i<mesh->get_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 + ".mesh", mesh);

	return err;
}
예제 #12
0
Error EditorOBJImporter::_parse_material_library(const String &p_path, Map<String, Ref<SpatialMaterial> > &material_map, List<String> *r_missing_deps) {

	FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
	ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);

	Ref<SpatialMaterial> current;
	String current_name;
	String base_path = p_path.get_base_dir();
	while (true) {

		String l = f->get_line().strip_edges();

		if (l.begins_with("newmtl ")) {
			//vertex

			current_name = l.replace("newmtl", "").strip_edges();
			current.instance();
			material_map[current_name] = current;
		} else if (l.begins_with("Ka ")) {
			//uv
			print_line("Warning: Ambient light for material '" + current_name + "' is ignored in PBR");

		} else if (l.begins_with("Kd ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);
			Color c = current->get_albedo();
			c.r = v[1].to_float();
			c.g = v[2].to_float();
			c.b = v[3].to_float();
			current->set_albedo(c);
		} else if (l.begins_with("Ks ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);
			float r = v[1].to_float();
			float g = v[2].to_float();
			float b = v[3].to_float();
			float metalness = MAX(r, MAX(g, b));
			current->set_metallic(metalness);
		} else if (l.begins_with("Ns ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() != 2, ERR_INVALID_DATA);
			float s = v[1].to_float();
			current->set_metallic((1000.0 - s) / 1000.0);
		} else if (l.begins_with("d ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() != 2, ERR_INVALID_DATA);
			float d = v[1].to_float();
			Color c = current->get_albedo();
			c.a = d;
			current->set_albedo(c);
			if (c.a < 0.99) {
				current->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
			}
		} else if (l.begins_with("Tr ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() != 2, ERR_INVALID_DATA);
			float d = v[1].to_float();
			Color c = current->get_albedo();
			c.a = 1.0 - d;
			current->set_albedo(c);
			if (c.a < 0.99) {
				current->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
			}

		} else if (l.begins_with("map_Ka ")) {
			//uv
			print_line("Warning: Ambient light texture for material '" + current_name + "' is ignored in PBR");

		} else if (l.begins_with("map_Kd ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);

			String p = l.replace("map_Kd", "").replace("\\", "/").strip_edges();
			String path = base_path.plus_file(p);

			Ref<Texture> texture = ResourceLoader::load(path);

			if (texture.is_valid()) {
				current->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
			} else {
				r_missing_deps->push_back(path);
			}

		} else if (l.begins_with("map_Ks ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);

			String p = l.replace("map_Ks", "").replace("\\", "/").strip_edges();
			String path = base_path.plus_file(p);

			Ref<Texture> texture = ResourceLoader::load(path);

			if (texture.is_valid()) {
				current->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture);
			} else {
				r_missing_deps->push_back(path);
			}

		} else if (l.begins_with("map_Ns ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);

			String p = l.replace("map_Ns", "").replace("\\", "/").strip_edges();
			String path = base_path.plus_file(p);

			Ref<Texture> texture = ResourceLoader::load(path);

			if (texture.is_valid()) {
				current->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, texture);
			} else {
				r_missing_deps->push_back(path);
			}
		} else if (l.begins_with("map_bump ")) {
			//normal
			ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);

			String p = l.replace("map_bump", "").replace("\\", "/").strip_edges();
			String path = base_path.plus_file(p);

			Ref<Texture> texture = ResourceLoader::load(path);

			if (texture.is_valid()) {
				current->set_feature(SpatialMaterial::FEATURE_NORMAL_MAPPING, true);
				current->set_texture(SpatialMaterial::TEXTURE_NORMAL, texture);
			} else {
				r_missing_deps->push_back(path);
			}
		} else if (f->eof_reached()) {
			break;
		}
	}

	return OK;
}
예제 #13
0
Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){


	ERR_FAIL_COND_V(p_from->get_source_count()!=1,ERR_INVALID_PARAMETER);

	Ref<ResourceImportMetadata> from=p_from;

	String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0));
	FileAccessRef f = FileAccess::open(src_path,FileAccess::READ);
	ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);

	Ref<Mesh> mesh;
	Map<String,Ref<Material> > name_map;

	if (FileAccess::exists(p_path)) {
		mesh=ResourceLoader::load(p_path,"Mesh");
		if (mesh.is_valid()) {
			for(int i=0;i<mesh->get_surface_count();i++) {

				if (!mesh->surface_get_material(i).is_valid())
					continue;
				String name;
				if (mesh->surface_get_name(i)!="")
					name=mesh->surface_get_name(i);
				else
					name=vformat(TTR("Surface %d"),i+1);

				name_map[name]=mesh->surface_get_material(i);
			}

			while(mesh->get_surface_count()) {
				mesh->surface_remove(0);
			}
		}
	}

	if (!mesh.is_valid())
		mesh = Ref<Mesh>( memnew( Mesh ) );


	bool generate_normals=from->get_option("generate/normals");
	bool generate_tangents=from->get_option("generate/tangents");
	bool flip_faces=from->get_option("force/flip_faces");
	bool force_smooth=from->get_option("force/smooth_shading");
	bool weld_vertices=from->get_option("force/weld_vertices");
	float weld_tolerance=from->get_option("force/weld_tolerance");
	Vector<Vector3> vertices;
	Vector<Vector3> normals;
	Vector<Vector2> uvs;
	String name;

	Ref<SurfaceTool> 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<String> 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<String> 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<String> 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<String> v = l.split(" ",false);
			ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA);

			//not very fast, could be sped up


			Vector<String> 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;i<v.size()-1;i++) {

				face[2] = v[i+1].split("/");
				ERR_FAIL_COND_V(face[0].size()!=face[2].size(),ERR_PARSE_ERROR);
				for(int j=0;j<3;j++) {

					int idx=j;

					if (!flip_faces && idx<2) {
						idx=1^idx;
					}


					if (face[idx].size()==3) {
						int norm = face[idx][2].to_int()-1;
						ERR_FAIL_INDEX_V(norm,normals.size(),ERR_PARSE_ERROR);
						surf_tool->add_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();
		}
	}


	from->set_source_md5(0,FileAccess::get_md5(src_path));
	from->set_editor(get_name());
	mesh->set_import_metadata(from);

	//re-apply materials if exist
	for(int i=0;i<mesh->get_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_path,mesh);

	return err;
}
예제 #14
0
Vector<uint8_t> EditorSceneExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) {

	if (!EditorImportExport::get_singleton()->get_convert_text_scenes()) {
		return Vector<uint8_t>();
	}


	String extension = p_path.extension();

	//step 1 check if scene

	if (extension=="xml" || extension=="xres") {

		String type = ResourceLoader::get_resource_type(p_path);

		if (type!="PackedScene")
			return Vector<uint8_t>();

	} else if (extension!="tscn" && extension!="xscn") {
		return Vector<uint8_t>();
	}

	//step 2 check if cached

	uint64_t sd=0;
	String smd5;
	String gp = Globals::get_singleton()->globalize_path(p_path);
	String md5=gp.md5_text();
	String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/");

	bool valid=false;
	{
		//if existing, make sure it's valid
		FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::READ);
		if (f) {

			uint64_t d = f->get_line().strip_edges().to_int64();
			sd = FileAccess::get_modified_time(p_path);

			if (d==sd) {
				valid=true;
			} else {
				String cmd5 = f->get_line().strip_edges();
				smd5 = FileAccess::get_md5(p_path);
				if (cmd5==smd5) {
					valid=true;
				}
			}


		}
	}

	if (!valid) {
		//cache failed, convert
		DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);

		String copy = p_path+".convert."+extension;

		// a copy will allow loading the internal resources without conflicting with opened scenes
		da->copy(p_path,copy);

		//@todo for tscn use something more efficient

		Ref<PackedScene> copyres =  ResourceLoader::load(copy,"PackedScene");

		da->remove(copy);

		memdelete(da);

		ERR_FAIL_COND_V(!copyres.is_valid(),Vector<uint8_t>());

		Error err = ResourceSaver::save(tmp_path+"scnexp-"+md5+".scn",copyres);

		copyres=Ref<PackedScene>();

		ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>());

		FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::WRITE);

		if (sd==0)
			sd = FileAccess::get_modified_time(p_path);
		if (smd5==String())
			smd5 = FileAccess::get_md5(p_path);

		f->store_line(String::num(sd));
		f->store_line(smd5);
		f->store_line(gp); //source path for reference
	}


	Vector<uint8_t> ret = FileAccess::get_file_as_array(tmp_path+"scnexp-"+md5+".scn");

	p_path+=".converted.scn";

	return ret;

}
예제 #15
0
파일: power_x11.cpp 프로젝트: 93i/godot
/* http://lxr.linux.no/linux+v2.6.29/drivers/char/apm-emulation.c */
bool PowerX11::GetPowerInfo_Linux_proc_apm() {
	bool need_details = false;
	int ac_status = 0;
	int battery_status = 0;
	int battery_flag = 0;
	int battery_percent = 0;
	int battery_time = 0;
	FileAccessRef fd = FileAccess::open(proc_apm_path, FileAccess::READ);
	char buf[128];
	char *ptr = &buf[0];
	char *str = NULL;
	ssize_t br;

	if (!fd) {
		return false; /* can't use this interface. */
	}

	br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), sizeof(buf) - 1);
	fd->close();

	if (br < 0) {
		return false;
	}

	buf[br] = '\0'; /* null-terminate the string. */
	if (!next_string(&ptr, &str)) { /* driver version */
		return false;
	}
	if (!next_string(&ptr, &str)) { /* BIOS version */
		return false;
	}
	if (!next_string(&ptr, &str)) { /* APM flags */
		return false;
	}

	if (!next_string(&ptr, &str)) { /* AC line status */
		return false;
	} else if (!int_string(str, &ac_status)) {
		return false;
	}

	if (!next_string(&ptr, &str)) { /* battery status */
		return false;
	} else if (!int_string(str, &battery_status)) {
		return false;
	}
	if (!next_string(&ptr, &str)) { /* battery flag */
		return false;
	} else if (!int_string(str, &battery_flag)) {
		return false;
	}
	if (!next_string(&ptr, &str)) { /* remaining battery life percent */
		return false;
	}
	String sstr = str;
	if (sstr[sstr.length() - 1] == '%') {
		sstr[sstr.length() - 1] = '\0';
	}
	if (!int_string(str, &battery_percent)) {
		return false;
	}

	if (!next_string(&ptr, &str)) { /* remaining battery life time */
		return false;
	} else if (!int_string(str, &battery_time)) {
		return false;
	}

	if (!next_string(&ptr, &str)) { /* remaining battery life time units */
		return false;
	} else if (String(str) == "min") {
		battery_time *= 60;
	}

	if (battery_flag == 0xFF) { /* unknown state */
		this->power_state = OS::POWERSTATE_UNKNOWN;
	} else if (battery_flag & (1 << 7)) { /* no battery */
		this->power_state = OS::POWERSTATE_NO_BATTERY;
	} else if (battery_flag & (1 << 3)) { /* charging */
		this->power_state = OS::POWERSTATE_CHARGING;
		need_details = true;
	} else if (ac_status == 1) {
		this->power_state = OS::POWERSTATE_CHARGED; /* on AC, not charging. */
		need_details = true;
	} else {
		this->power_state = OS::POWERSTATE_ON_BATTERY;
		need_details = true;
	}

	this->percent_left = -1;
	this->nsecs_left = -1;
	if (need_details) {
		const int pct = battery_percent;
		const int secs = battery_time;

		if (pct >= 0) { /* -1 == unknown */
			this->percent_left = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */
		}
		if (secs >= 0) { /* -1 == unknown */
			this->nsecs_left = secs;
		}
	}

	return true;
}
Error ResourceImporterCSVTranslation::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) {

	bool compress = p_options["compress"];

	String delimiter;
	switch ((int)p_options["delimiter"]) {
		case 0: delimiter = ","; break;
		case 1: delimiter = ";"; break;
		case 2: delimiter = "\t"; break;
	}

	FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);

	ERR_FAIL_COND_V(!f, ERR_INVALID_PARAMETER);

	Vector<String> line = f->get_csv_line(delimiter);
	ERR_FAIL_COND_V(line.size() <= 1, ERR_PARSE_ERROR);

	Vector<String> locales;
	Vector<Ref<Translation> > translations;

	for (int i = 1; i < line.size(); i++) {

		String locale = line[i];
		ERR_EXPLAIN("Error importing CSV translation: '" + locale + "' is not a valid locale");
		ERR_FAIL_COND_V(!TranslationServer::is_locale_valid(locale), ERR_PARSE_ERROR);

		locales.push_back(locale);
		Ref<Translation> translation;
		translation.instance();
		translation->set_locale(locale);
		translations.push_back(translation);
	}

	line = f->get_csv_line(delimiter);

	while (line.size() == locales.size() + 1) {

		String key = line[0];
		if (key != "") {

			for (int i = 1; i < line.size(); i++) {
				translations.write[i - 1]->add_message(key, line[i]);
			}
		}

		line = f->get_csv_line(delimiter);
	}

	for (int i = 0; i < translations.size(); i++) {
		Ref<Translation> xlt = translations[i];

		if (compress) {
			Ref<PHashTranslation> cxl = memnew(PHashTranslation);
			cxl->generate(xlt);
			xlt = cxl;
		}

		String save_path = p_source_file.get_basename() + "." + translations[i]->get_locale() + ".translation";

		ResourceSaver::save(save_path, xlt);
		if (r_gen_files) {
			r_gen_files->push_back(save_path);
		}
	}

	return OK;
}
예제 #17
0
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {

	FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);

	if (r_err) {
		*r_err = ERR_CANT_OPEN;
	}

	ERR_FAIL_COND_V(!f, NULL);

	if (r_err) {
		*r_err = OK;
	}

	Spatial *scene = memnew(Spatial);

	Ref<ArrayMesh> mesh;
	mesh.instance();

	Map<String, Ref<Material> > name_map;

	bool generate_tangents = p_flags & IMPORT_GENERATE_TANGENT_ARRAYS;
	bool flip_faces = false;
	//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<Vector3> vertices;
	Vector<Vector3> normals;
	Vector<Vector2> uvs;
	String name;

	Map<String, Map<String, Ref<SpatialMaterial> > > material_map;

	Ref<SurfaceTool> surf_tool = memnew(SurfaceTool);
	surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);

	String current_material_library;
	String current_material;
	String current_group;

	while (true) {

		String l = f->get_line().strip_edges();

		if (l.begins_with("v ")) {
			//vertex
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, NULL);
			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<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 3, NULL);
			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<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, NULL);
			Vector3 nrm;
			nrm.x = v[1].to_float();
			nrm.y = v[2].to_float();
			nrm.z = v[3].to_float();
			normals.push_back(nrm);
		} else if (l.begins_with("f ")) {
			//vertex

			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, NULL);

			//not very fast, could be sped up

			Vector<String> face[3];
			face[0] = v[1].split("/");
			face[1] = v[2].split("/");
			ERR_FAIL_COND_V(face[0].size() == 0, NULL);
			ERR_FAIL_COND_V(face[0].size() != face[1].size(), NULL);
			for (int i = 2; i < v.size() - 1; i++) {

				face[2] = v[i + 1].split("/");
				ERR_FAIL_COND_V(face[0].size() != face[2].size(), NULL);
				for (int j = 0; j < 3; j++) {

					int idx = j;

					if (!flip_faces && idx < 2) {
						idx = 1 ^ idx;
					}

					if (face[idx].size() == 3) {
						int norm = face[idx][2].to_int() - 1;
						if (norm < 0)
							norm += normals.size() + 1;
						ERR_FAIL_INDEX_V(norm, normals.size(), NULL);
						surf_tool->add_normal(normals[norm]);
					}

					if (face[idx].size() >= 2 && face[idx][1] != String()) {
						int uv = face[idx][1].to_int() - 1;
						if (uv < 0)
							uv += uvs.size() + 1;
						ERR_FAIL_INDEX_V(uv, uvs.size(), NULL);
						surf_tool->add_uv(uvs[uv]);
					}

					int vtx = face[idx][0].to_int() - 1;
					if (vtx < 0)
						vtx += vertices.size() + 1;
					ERR_FAIL_INDEX_V(vtx, vertices.size(), NULL);

					Vector3 vertex = vertices[vtx];
					//if (weld_vertices)
					//	vertex.snap(Vector3(weld_tolerance, weld_tolerance, weld_tolerance));
					surf_tool->add_vertex(vertex);
				}

				face[1] = face[2];
			}
		} else if (l.begins_with("s ")) { //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("g ") ||*/ l.begins_with("usemtl ") || (l.begins_with("o ") || f->eof_reached())) { //commit group to mesh
			//groups are too annoying
			if (surf_tool->get_vertex_array().size()) {
				//another group going on, commit it
				if (normals.size() == 0) {
					surf_tool->generate_normals();
				}

				if (generate_tangents && uvs.size()) {
					surf_tool->generate_tangents();
				}

				surf_tool->index();

				print_line("current material library " + current_material_library + " has " + itos(material_map.has(current_material_library)));
				print_line("current material " + current_material + " has " + itos(material_map.has(current_material_library) && material_map[current_material_library].has(current_material)));

				if (material_map.has(current_material_library) && material_map[current_material_library].has(current_material)) {
					surf_tool->set_material(material_map[current_material_library][current_material]);
				}

				mesh = surf_tool->commit(mesh);

				if (current_material != String()) {
					mesh->surface_set_name(mesh->get_surface_count() - 1, current_material.get_basename());
				} else if (current_group != String()) {
					mesh->surface_set_name(mesh->get_surface_count() - 1, current_group);
				}

				print_line("Added surface :" + mesh->surface_get_name(mesh->get_surface_count() - 1));
				surf_tool->clear();
				surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
			}

			if (l.begins_with("o ") || f->eof_reached()) {

				MeshInstance *mi = memnew(MeshInstance);
				mi->set_name(name);
				mi->set_mesh(mesh);

				scene->add_child(mi);
				mi->set_owner(scene);

				mesh.instance();
				current_group = "";
				current_material = "";
			}

			if (f->eof_reached()) {
				break;
			}

			if (l.begins_with("o ")) {
				name = l.substr(2, l.length()).strip_edges();
			}

			if (l.begins_with("usemtl ")) {

				current_material = l.replace("usemtl", "").strip_edges();
			}

			if (l.begins_with("g ")) {

				current_group = l.substr(2, l.length()).strip_edges();
			}

		} else if (l.begins_with("mtllib ")) { //parse material

			current_material_library = l.replace("mtllib", "").strip_edges();
			if (!material_map.has(current_material_library)) {
				Map<String, Ref<SpatialMaterial> > lib;
				Error err = _parse_material_library(current_material_library, lib, r_missing_deps);
				if (err == ERR_CANT_OPEN) {
					String dir = p_path.get_base_dir();
					err = _parse_material_library(dir.plus_file(current_material_library), lib, r_missing_deps);
				}
				if (err == OK) {
					material_map[current_material_library] = lib;
				}
			}
		}
	}

	/*
	TODO, check existing materials and merge?
	//re-apply materials if exist
	for(int i=0;i<mesh->get_surface_count();i++) {

		String n = mesh->surface_get_name(i);
		if (name_map.has(n))
			mesh->surface_set_material(i,name_map[n]);
	}
*/

	return scene;
}
예제 #18
0
void EditorFileSystem::_scan_filesystem() {

	ERR_FAIL_COND(!scanning || new_filesystem);

	//read .fscache
	String cpath;

	sources_changed.clear();
	file_cache.clear();

	String project = ProjectSettings::get_singleton()->get_resource_path();

	String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2");
	FileAccess *f = FileAccess::open(fscache, FileAccess::READ);

	if (f) {
		//read the disk cache
		while (!f->eof_reached()) {

			String l = f->get_line().strip_edges();
			if (l == String())
				continue;

			if (l.begins_with("::")) {
				Vector<String> split = l.split("::");
				ERR_CONTINUE(split.size() != 3);
				String name = split[1];

				cpath = name;

			} else {
				Vector<String> split = l.split("::");
				ERR_CONTINUE(split.size() != 5);
				String name = split[0];
				String file;

				file = name;
				name = cpath.plus_file(name);

				FileCache fc;
				fc.type = split[1];
				fc.modification_time = split[2].to_int64();
				fc.import_modification_time = split[3].to_int64();

				String deps = split[4].strip_edges();
				if (deps.length()) {
					Vector<String> dp = deps.split("<>");
					for (int i = 0; i < dp.size(); i++) {
						String path = dp[i];
						fc.deps.push_back(path);
					}
				}

				file_cache[name] = fc;
			}
		}

		f->close();
		memdelete(f);
	}

	String update_cache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update2");

	print_line("try to see fs update2");
	if (FileAccess::exists(update_cache)) {

		print_line("it exists");

		{
			FileAccessRef f = FileAccess::open(update_cache, FileAccess::READ);
			String l = f->get_line().strip_edges();
			while (l != String()) {

				print_line("erased cache for: " + l + " " + itos(file_cache.has(l)));
				file_cache.erase(l); //erase cache for this, so it gets updated
				l = f->get_line().strip_edges();
			}
		}

		DirAccessRef d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
		d->remove(update_cache); //bye bye update cache
	}

	EditorProgressBG scan_progress("efs", "ScanFS", 1000);

	ScanProgress sp;
	sp.low = 0;
	sp.hi = 1;
	sp.progress = &scan_progress;

	new_filesystem = memnew(EditorFileSystemDirectory);
	new_filesystem->parent = NULL;

	DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
	d->change_dir("res://");
	_scan_new_dir(new_filesystem, d, sp);

	file_cache.clear(); //clear caches, no longer needed

	memdelete(d);

	//save back the findings
	//String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("file_cache");

	f = FileAccess::open(fscache, FileAccess::WRITE);
	_save_filesystem_cache(new_filesystem, f);
	f->close();
	memdelete(f);

	scanning = false;
}
예제 #19
0
static bool _get_token(FileAccessRef& f,uint8_t &saved,PoolVector<uint8_t>& r_token,bool p_binary=false,bool p_single_chunk=false) {


	int token_max = r_token.size();
	PoolVector<uint8_t>::Write w;
	if (token_max)
		w=r_token.write();
	int ofs=0;
	bool lf=false;


	while(true) {

		uint8_t b;
		if (saved) {
			b=saved;
			saved=0;
		} else {
			b = f->get_8();
		}
		if (f->eof_reached()) {
			if (ofs) {
				w=PoolVector<uint8_t>::Write();
				r_token.resize(ofs);
				return true;
			} else {
				return false;
			}
		}

		if (!ofs && !p_binary && b=='#') {
			//skip comment
			while(b!='\n') {
				if (f->eof_reached()) {
					return false;
				}

				b = f->get_8();
			}

			lf=true;

		} else if (b<=32 && !(p_binary && (ofs || lf))) {

			if (b=='\n') {
				lf=true;
			}


			if (ofs && !p_single_chunk) {
				w=PoolVector<uint8_t>::Write();
				r_token.resize(ofs);
				saved=b;

				return true;
			}
		} else {

			bool resized=false;
			while (ofs>=token_max) {
				if (token_max)
					token_max<<=1;
				else
					token_max=1;
				resized=true;
			}
			if (resized) {
				w=PoolVector<uint8_t>::Write();
				r_token.resize(token_max);
				w=r_token.write();
			}
			w[ofs++]=b;
		}
	}

	return false;
}