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; }
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; }
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()); }
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; }
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()); } }
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()); } }
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); }
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)); } }
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(); } }
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); } }
_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 }
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; }