Пример #1
0
void ScriptDebuggerLocal::profiling_end() {

	int ofs = 0;

	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
		ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo[ofs], pinfo.size() - ofs);
	}

	SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;
	sort.sort(pinfo.ptr(), ofs);

	uint64_t total_us = 0;
	for (int i = 0; i < ofs; i++) {
		total_us += pinfo[i].self_time;
	}

	float total_time = total_us / 1000000.0;

	for (int i = 0; i < ofs; i++) {

		print_line(itos(i) + ":" + pinfo[i].signature);
		float tt = USEC_TO_SEC(pinfo[i].total_time);
		float st = USEC_TO_SEC(pinfo[i].self_time);
		print_line("\ttotal_ms: " + rtos(tt) + "\tself_ms: " + rtos(st) + "total%: " + itos(tt * 100 / total_time) + "\tself%: " + itos(st * 100 / total_time) + "\tcalls: " + itos(pinfo[i].call_count));
	}

	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
		ScriptServer::get_language(i)->profiling_stop();
	}

	profiling = false;
}
Пример #2
0
int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh,int p_len,int p_depth) {

	if (p_len==1) {

		bvh_depth=MAX(p_depth,bvh_depth);
		bvh.push_back(*p_bvh);
		return bvh.size()-1;
	}

	//else sort best

	Rect2 global_aabb=p_bvh[0].aabb;
	for(int i=1;i<p_len;i++) {
		global_aabb=global_aabb.merge(p_bvh[i].aabb);
	}

	if (global_aabb.size.x > global_aabb.size.y) {

		SortArray<BVH,BVH_CompareX> sort;
		sort.sort(p_bvh,p_len);

	} else {

		SortArray<BVH,BVH_CompareY> sort;
		sort.sort(p_bvh,p_len);

	}

	int median = p_len/2;


	BVH node;
	node.aabb=global_aabb;
	int node_idx = bvh.size();
	bvh.push_back(node);

	int l = _generate_bvh(p_bvh,median,p_depth+1);
	int r = _generate_bvh(&p_bvh[median],p_len-median,p_depth+1);
	bvh[node_idx].left=l;
	bvh[node_idx].right=r;

	return node_idx;

}
Пример #3
0
void Array::sort_custom(Object *p_obj,const StringName& p_function){

	ERR_FAIL_NULL(p_obj);

	SortArray<Variant,_ArrayVariantSortCustom> avs;
	avs.compare.obj=p_obj;
	avs.compare.func=p_function;
	avs.sort(_p->array.ptr(),_p->array.size());

}
Пример #4
0
Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {

	ERR_FAIL_NULL_V(p_obj, *this);

	SortArray<Variant, _ArrayVariantSortCustom, true> avs;
	avs.compare.obj = p_obj;
	avs.compare.func = p_function;
	avs.sort(_p->array.ptrw(), _p->array.size());
	return *this;
}
Пример #5
0
void VoxelMeshUpdater::thread_sync(int queue_index, Stats stats) {

	if (!_input.blocks.empty()) {
		// Cleanup input vector

		if (queue_index >= _input.blocks.size()) {
			_input.blocks.clear();

		} else if (queue_index > 0) {

			// Shift up remaining items since we use a Vector
			shift_up(_input.blocks, queue_index);
		}
	}

	stats.remaining_blocks = _input.blocks.size();
	bool needs_sort;

	{
		// Get input
		MutexLock lock(_input_mutex);

		_input.blocks.append_array(_shared_input.blocks);
		_input.priority_position = _shared_input.priority_position;

		_shared_input.blocks.clear();
		_block_indexes.clear();

		needs_sort = _needs_sort;
		_needs_sort = false;
	}

	if(!_output.blocks.empty()) {

//		print_line(String("VoxelMeshUpdater: posting {0} blocks, {1} remaining ; cost [{2}..{3}] usec")
//				   .format(varray(_output.blocks.size(), _input.blocks.size(), stats.min_time, stats.max_time)));

		// Post output
		MutexLock lock(_output_mutex);
		_shared_output.blocks.append_array(_output.blocks);
		_shared_output.stats = stats;
		_output.blocks.clear();
	}

	if (!_input.blocks.empty() && needs_sort) {
		// Re-sort priority

		SortArray<VoxelMeshUpdater::InputBlock, BlockUpdateComparator> sorter;
		sorter.compare.center = _input.priority_position;
		sorter.sort(_input.blocks.ptrw(), _input.blocks.size());
	}
}
Пример #6
0
void VoxelProviderThread::thread_sync(int emerge_index, Stats stats) {

	if (!_input.blocks_to_emerge.empty()) {
		// Cleanup emerge vector

		if (emerge_index >= _input.blocks_to_emerge.size()) {
			_input.blocks_to_emerge.clear();

		} else if (emerge_index > 0) {

			// Shift up remaining items since we use a Vector
			shift_up(_input.blocks_to_emerge, emerge_index);
		}
	}

	{
		// Get input
		MutexLock lock(_input_mutex);

		_input.blocks_to_emerge.append_array(_shared_input.blocks_to_emerge);
		_input.blocks_to_immerge.append_array(_shared_input.blocks_to_immerge);
		_input.priority_block_position = _shared_input.priority_block_position;

		_shared_input.blocks_to_emerge.clear();
		_shared_input.blocks_to_immerge.clear();
	}

	stats.remaining_blocks = _input.blocks_to_emerge.size();

//	print_line(String("VoxelProviderThread: posting {0} blocks, {1} remaining ; cost [{2}..{3}] usec")
//			   .format(varray(_output.size(), _input.blocks_to_emerge.size(), stats.min_time, stats.max_time)));

	{
		// Post output
		MutexLock lock(_output_mutex);
		_shared_output.append_array(_output);
		_shared_stats = stats;
		_output.clear();
	}

	if (!_input.blocks_to_emerge.empty()) {
		// Re-sort priority

		SortArray<Vector3i, BlockPositionComparator> sorter;
		sorter.compare.center = _input.priority_block_position;
		sorter.sort(_input.blocks_to_emerge.ptrw(), _input.blocks_to_emerge.size());
	}
}
Пример #7
0
static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {

#ifdef DEBUG_ENABLED
	ERR_FAIL_COND(p_point_count_A != 2);
	ERR_FAIL_COND(p_point_count_B != 2); // circle is actually a 4x3 matrix
#endif

	Vector3 rel_A = p_points_A[1] - p_points_A[0];
	Vector3 rel_B = p_points_B[1] - p_points_B[0];

	Vector3 c = rel_A.cross(rel_B).cross(rel_B);

	//if ( Math::abs(rel_A.dot(c) )<_EDGE_IS_VALID_SUPPORT_TRESHOLD ) {
	if (Math::abs(rel_A.dot(c)) < CMP_EPSILON) {

		// should handle somehow..
		//ERR_PRINT("TODO FIX");
		//return;

		Vector3 axis = rel_A.normalized(); //make an axis
		Vector3 base_A = p_points_A[0] - axis * axis.dot(p_points_A[0]);
		Vector3 base_B = p_points_B[0] - axis * axis.dot(p_points_B[0]);

		//sort all 4 points in axis
		real_t dvec[4] = { axis.dot(p_points_A[0]), axis.dot(p_points_A[1]), axis.dot(p_points_B[0]), axis.dot(p_points_B[1]) };

		SortArray<real_t> sa;
		sa.sort(dvec, 4);

		//use the middle ones as contacts
		p_callback->call(base_A + axis * dvec[1], base_B + axis * dvec[1]);
		p_callback->call(base_A + axis * dvec[2], base_B + axis * dvec[2]);

		return;
	}

	real_t d = (c.dot(p_points_B[0]) - p_points_A[0].dot(c)) / rel_A.dot(c);

	if (d < 0.0)
		d = 0.0;
	else if (d > 1.0)
		d = 1.0;

	Vector3 closest_A = p_points_A[0] + rel_A * d;
	Vector3 closest_B = Geometry::get_closest_point_to_segment_uncapped(closest_A, p_points_B);
	p_callback->call(closest_A, closest_B);
}
Пример #8
0
void ScriptDebuggerLocal::idle_poll() {

	if (!profiling)
		return;

	uint64_t diff = OS::get_singleton()->get_ticks_usec() - idle_accum;

	if (diff < 1000000) //show every one second
		return;

	idle_accum = OS::get_singleton()->get_ticks_usec();

	int ofs = 0;
	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
		ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo[ofs], pinfo.size() - ofs);
	}

	SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort;
	sort.sort(pinfo.ptr(), ofs);

	//falta el frame time

	uint64_t script_time_us = 0;

	for (int i = 0; i < ofs; i++) {

		script_time_us += pinfo[i].self_time;
	}

	float script_time = USEC_TO_SEC(script_time_us);

	float total_time = frame_time;

	//print script total

	print_line("FRAME: total: " + rtos(frame_time) + " script: " + rtos(script_time) + "/" + itos(script_time * 100 / total_time) + " %");

	for (int i = 0; i < ofs; i++) {

		print_line(itos(i) + ":" + pinfo[i].signature);
		float tt = USEC_TO_SEC(pinfo[i].total_time);
		float st = USEC_TO_SEC(pinfo[i].self_time);
		print_line("\ttotal: " + rtos(tt) + "/" + itos(tt * 100 / total_time) + " % \tself: " + rtos(st) + "/" + itos(st * 100 / total_time) + " % tcalls: " + itos(pinfo[i].call_count));
	}
}
Пример #9
0
void ScriptDebuggerRemote::_send_profiling_data(bool p_for_frame) {

	int ofs = 0;

	for (int i = 0; i < ScriptServer::get_language_count(); i++) {
		if (p_for_frame)
			ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info[ofs], profile_info.size() - ofs);
		else
			ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info[ofs], profile_info.size() - ofs);
	}

	for (int i = 0; i < ofs; i++) {
		profile_info_ptrs[i] = &profile_info[i];
	}

	SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa;
	sa.sort(profile_info_ptrs.ptr(), ofs);

	int to_send = MIN(ofs, max_frame_functions);

	//check signatures first
	uint64_t total_script_time = 0;

	for (int i = 0; i < to_send; i++) {

		if (!profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) {

			int idx = profiler_function_signature_map.size();
			packet_peer_stream->put_var("profile_sig");
			packet_peer_stream->put_var(2);
			packet_peer_stream->put_var(profile_info_ptrs[i]->signature);
			packet_peer_stream->put_var(idx);

			profiler_function_signature_map[profile_info_ptrs[i]->signature] = idx;
		}

		total_script_time += profile_info_ptrs[i]->self_time;
	}

	//send frames then

	if (p_for_frame) {
		packet_peer_stream->put_var("profile_frame");
		packet_peer_stream->put_var(8 + profile_frame_data.size() * 2 + to_send * 4);
	} else {
		packet_peer_stream->put_var("profile_total");
		packet_peer_stream->put_var(8 + to_send * 4);
	}

	packet_peer_stream->put_var(Engine::get_singleton()->get_frames_drawn()); //total frame time
	packet_peer_stream->put_var(frame_time); //total frame time
	packet_peer_stream->put_var(idle_time); //idle frame time
	packet_peer_stream->put_var(fixed_time); //fixed frame time
	packet_peer_stream->put_var(fixed_frame_time); //fixed frame time

	packet_peer_stream->put_var(USEC_TO_SEC(total_script_time)); //total script execution time

	if (p_for_frame) {

		packet_peer_stream->put_var(profile_frame_data.size()); //how many profile framedatas to send
		packet_peer_stream->put_var(to_send); //how many script functions to send
		for (int i = 0; i < profile_frame_data.size(); i++) {

			packet_peer_stream->put_var(profile_frame_data[i].name);
			packet_peer_stream->put_var(profile_frame_data[i].data);
		}
	} else {
		packet_peer_stream->put_var(0); //how many script functions to send
		packet_peer_stream->put_var(to_send); //how many script functions to send
	}

	for (int i = 0; i < to_send; i++) {

		int sig_id = -1;

		if (profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) {
			sig_id = profiler_function_signature_map[profile_info_ptrs[i]->signature];
		}

		packet_peer_stream->put_var(sig_id);
		packet_peer_stream->put_var(profile_info_ptrs[i]->call_count);
		packet_peer_stream->put_var(profile_info_ptrs[i]->total_time / 1000000.0);
		packet_peer_stream->put_var(profile_info_ptrs[i]->self_time / 1000000.0);
	}

	if (p_for_frame) {
		profile_frame_data.clear();
	}
}
Пример #10
0
void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) {

	Item *ci = p_canvas_item;

	if (!ci->visible)
		return;

	Rect2 rect = ci->get_rect();
	Transform2D xform = p_transform * ci->xform;
	Rect2 global_rect = xform.xform(rect);
	global_rect.pos += p_clip_rect.pos;

	if (ci->use_parent_material && p_material_owner)
		ci->material_owner = p_material_owner;
	else {
		p_material_owner = ci;
		ci->material_owner = NULL;
	}

	Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a);

	if (modulate.a < 0.007)
		return;

	int child_item_count = ci->child_items.size();
	Item **child_items = (Item **)alloca(child_item_count * sizeof(Item *));
	copymem(child_items, ci->child_items.ptr(), child_item_count * sizeof(Item *));

	if (ci->clip) {
		if (p_canvas_clip != NULL) {
			ci->final_clip_rect = p_canvas_clip->final_clip_rect.clip(global_rect);
		} else {
			ci->final_clip_rect = global_rect;
		}
		ci->final_clip_owner = ci;

	} else {
		ci->final_clip_owner = p_canvas_clip;
	}

	if (ci->sort_y) {

		SortArray<Item *, ItemPtrSort> sorter;
		sorter.sort(child_items, child_item_count);
	}

	if (ci->z_relative)
		p_z = CLAMP(p_z + ci->z, VS::CANVAS_ITEM_Z_MIN, VS::CANVAS_ITEM_Z_MAX);
	else
		p_z = ci->z;

	for (int i = 0; i < child_item_count; i++) {

		if (!child_items[i]->behind)
			continue;
		_render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
	}

	if (ci->copy_back_buffer) {

		ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect);
	}

	if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render || ci->copy_back_buffer) {
		//something to draw?
		ci->final_transform = xform;
		ci->final_modulate = Color(modulate.r * ci->self_modulate.r, modulate.g * ci->self_modulate.g, modulate.b * ci->self_modulate.b, modulate.a * ci->self_modulate.a);
		ci->global_rect_cache = global_rect;
		ci->global_rect_cache.pos -= p_clip_rect.pos;
		ci->light_masked = false;

		int zidx = p_z - VS::CANVAS_ITEM_Z_MIN;

		if (z_last_list[zidx]) {
			z_last_list[zidx]->next = ci;
			z_last_list[zidx] = ci;

		} else {
			z_list[zidx] = ci;
			z_last_list[zidx] = ci;
		}

		ci->next = NULL;
	}

	for (int i = 0; i < child_item_count; i++) {

		if (child_items[i]->behind)
			continue;
		_render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
	}
}
Пример #11
0
_FORCE_INLINE_ static void _generate_contacts_edge_edge(const Vector2 * p_points_A,int p_point_count_A, const Vector2 * p_points_B,int p_point_count_B,_CollectorCallback2D *p_collector) {

#ifdef DEBUG_ENABLED
	ERR_FAIL_COND( p_point_count_A != 2 );
	ERR_FAIL_COND( p_point_count_B != 2 ); // circle is actually a 4x3 matrix
#endif


	Vector2 rel_A=p_points_A[1]-p_points_A[0];
	Vector2 rel_B=p_points_B[1]-p_points_B[0];

	Vector2 t = p_collector->normal.tangent();

	real_t dA[2]={t.dot(p_points_A[0]),t.dot(p_points_A[1])};
	Vector2 pA[2]={p_points_A[0],p_points_A[1]};

	if (dA[0]>dA[1]) {
		SWAP(dA[0],dA[1]);
		SWAP(pA[0],pA[1]);
	}

	float dB[2]={t.dot(p_points_B[0]),t.dot(p_points_B[1])};
	Vector2 pB[2]={p_points_B[0],p_points_B[1]};
	if (dB[0]>dB[1]) {
		SWAP(dB[0],dB[1]);
		SWAP(pB[0],pB[1]);
	}


	if (dA[0]<dB[0]) {

		Vector2 n = (p_points_A[1]-p_points_A[0]).normalized().tangent();
		real_t d = n.dot(p_points_A[1]);

		if (dA[1]>dB[1]) {
			//A contains B
			for(int i=0;i<2;i++) {

				Vector2 b = p_points_B[i];
				Vector2 a = n.plane_project(d,b);
				if (p_collector->normal.dot(a) > p_collector->normal.dot(b)-CMP_EPSILON)
					continue;
				p_collector->call(a,b);

			}
		} else {

			// B0,A1 containment

			Vector2 n_B = (p_points_B[1]-p_points_B[0]).normalized().tangent();
			real_t d_B = n_B.dot(p_points_B[1]);

			// first, B on A

			{
				Vector2 b = p_points_B[0];
				Vector2 a = n.plane_project(d,b);
				if (p_collector->normal.dot(a) < p_collector->normal.dot(b)-CMP_EPSILON)
					p_collector->call(a,b);
			}

			// second, A on B

			{
				Vector2 a = p_points_A[1];
				Vector2 b = n_B.plane_project(d_B,a);
				if (p_collector->normal.dot(a) < p_collector->normal.dot(b)-CMP_EPSILON)
					p_collector->call(a,b);
			}



		}


	} else {

		Vector2 n = (p_points_B[1]-p_points_B[0]).normalized().tangent();
		real_t d = n.dot(p_points_B[1]);

		if (dB[1]>dA[1]) {
			//B contains A
			for(int i=0;i<2;i++) {

				Vector2 a = p_points_A[i];
				Vector2 b = n.plane_project(d,a);
				if (p_collector->normal.dot(a) > p_collector->normal.dot(b)-CMP_EPSILON)
					continue;
				p_collector->call(a,b);
			}
		} else {

			// A0,B1 containment
			Vector2 n_A = (p_points_A[1]-p_points_A[0]).normalized().tangent();
			real_t d_A = n_A.dot(p_points_A[1]);

			// first A on B

			{
				Vector2 a = p_points_A[0];
				Vector2 b = n.plane_project(d,a);
				if (p_collector->normal.dot(a) < p_collector->normal.dot(b)-CMP_EPSILON)
					p_collector->call(a,b);

			}

			//second, B on A

			{

				Vector2 b = p_points_B[1];
				Vector2 a = n_A.plane_project(d_A,b);
				if (p_collector->normal.dot(a) < p_collector->normal.dot(b)-CMP_EPSILON)
					p_collector->call(a,b);
			}

		}
	}


#if 0

	Vector2 axis = rel_A.normalized();
	Vector2 axis_B = rel_B.normalized();
	if (axis.dot(axis_B)<0)
		axis_B=-axis_B;
	axis=(axis+axis_B)*0.5;

	Vector2 normal_A = axis.tangent();
	real_t dA = normal_A.dot(p_points_A[0]);
	Vector2 normal_B = rel_B.tangent().normalized();
	real_t dB = normal_A.dot(p_points_B[0]);

	Vector2 A[4]={ normal_A.plane_project(dA,p_points_B[0]), normal_A.plane_project(dA,p_points_B[1]), p_points_A[0], p_points_A[1] };
	Vector2 B[4]={ p_points_B[0], p_points_B[1], normal_B.plane_project(dB,p_points_A[0]), normal_B.plane_project(dB,p_points_A[1]) };

	_generate_contacts_Pair dvec[4];
	for(int i=0;i<4;i++) {
		dvec[i].d=axis.dot(p_points_A[0]-A[i]);
		dvec[i].idx=i;
	}

	SortArray<_generate_contacts_Pair> sa;
	sa.sort(dvec,4);

	for(int i=1;i<=2;i++) {

		Vector2 a = A[i];
		Vector2 b = B[i];
		if (p_collector->normal.dot(a) > p_collector->normal.dot(b)-CMP_EPSILON)
			continue;
		p_collector->call(a,b);
	}

#elif 0
	Vector2 axis = rel_A.normalized(); //make an axis
	Vector2 axis_B = rel_B.normalized();
	if (axis.dot(axis_B)<0)
		axis_B=-axis_B;
	axis=(axis+axis_B)*0.5;
	Vector2 base_A = p_points_A[0] - axis * axis.dot(p_points_A[0]);
	Vector2 base_B = p_points_B[0] - axis * axis.dot(p_points_B[0]);

	//sort all 4 points in axis
	float dvec[4]={ axis.dot(p_points_A[0]), axis.dot(p_points_A[1]), axis.dot(p_points_B[0]), axis.dot(p_points_B[1]) };

	//todo , find max/min and then use 2 central points
	SortArray<float> sa;
	sa.sort(dvec,4);

	//use the middle ones as contacts
	for (int i=1;i<=2;i++) {

		Vector2 a = base_A+axis*dvec[i];
		Vector2 b = base_B+axis*dvec[i];
		if (p_collector->normal.dot(a) > p_collector->normal.dot(b)-0.01) {
			print_line("fail a: "+a);
			print_line("fail b: "+b);
			continue;
		}
		print_line("res a: "+a);
		print_line("res b: "+b);
		p_collector->call(a,b);
	}
#endif
}
Пример #12
0
Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const {


	Set<StringName> exported;

	if (FileAccess::exists("res://engine.cfg"))
		exported.insert("res://engine.cfg");

	if (EditorImportExport::get_singleton()->get_export_filter()!=EditorImportExport::EXPORT_SELECTED) {

		String filter;
		if (EditorImportExport::get_singleton()->get_export_filter()==EditorImportExport::EXPORT_ALL) {
			_add_filter_to_list(exported,"*");
		} else {
			_add_to_list(EditorFileSystem::get_singleton()->get_filesystem(),exported);
			_add_filter_to_list(exported,EditorImportExport::get_singleton()->get_export_custom_filter());

		}


	} else {


		Map<String,Map<String,String> > remapped_paths;

		Set<String> scene_extensions;
		Set<String> resource_extensions;

		{

			List<String> l;
	//		SceneLoader::get_recognized_extensions(&l);
	//		for(List<String>::Element *E=l.front();E;E=E->next()) {
	//
	//			scene_extensions.insert(E->get());
	//		}
			ResourceLoader::get_recognized_extensions_for_type("",&l);
			for(List<String>::Element *E=l.front();E;E=E->next()) {

				resource_extensions.insert(E->get());
			}
		}


		List<StringName> toexport;

		EditorImportExport::get_singleton()->get_export_file_list(&toexport);

		print_line("TO EXPORT: "+itos(toexport.size()));


		for (List<StringName>::Element *E=toexport.front();E;E=E->next()) {

			print_line("DEP: "+String(E->get()));
			exported.insert(E->get());
			if (p_bundles && EditorImportExport::get_singleton()->get_export_file_action(E->get())==EditorImportExport::ACTION_BUNDLE) {
				print_line("NO BECAUSE OF BUNDLE!");
				continue; //no dependencies needed to be copied
			}

			List<String> testsubs;
			testsubs.push_back(E->get());

			while(testsubs.size()) {
				//recursive subdep search!
				List<String> deplist;
				ResourceLoader::get_dependencies(testsubs.front()->get(),&deplist);
				testsubs.pop_front();

				List<String> subdeps;

				for (List<String>::Element *F=deplist.front();F;F=F->next()) {

					StringName dep = F->get();

					if (exported.has(dep) || EditorImportExport::get_singleton()->get_export_file_action(dep)!=EditorImportExport::ACTION_NONE)
						continue; //dependency added or to be added
					print_line(" SUBDEP: "+String(dep));

					exported.insert(dep);
					testsubs.push_back(dep);
				}
			}
		}

		_add_filter_to_list(exported,EditorImportExport::get_singleton()->get_export_custom_filter());

	}

	Vector<StringName> ret;
	ret.resize(exported.size());


	int idx=0;
	for(Set<StringName>::Element *E=exported.front();E;E=E->next()) {

		ret[idx++]=E->get();

	}

	SortArray<StringName,__EESortDepCmp> sort; //some platforms work better if this is sorted
	sort.sort(ret.ptr(),ret.size());

	return ret;

}