int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { const Rect2 aabb = E->get().aabb; if (aabb.intersects(p_aabb)) { p_results[rc] = E->get().owner; p_result_indices[rc] = E->get().subindex; rc++; if (rc >= p_max_results) break; } } return rc; }
int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { pass++; Point2i from = (p_aabb.position / cell_size).floor(); Point2i to = ((p_aabb.position + p_aabb.size) / cell_size).floor(); int cullcount = 0; for (int i = from.x; i <= to.x; i++) { for (int j = from.y; j <= to.y; j++) { _cull<true, false>(Point2i(i, j), p_aabb, Point2(), Point2(), p_results, p_max_results, p_result_indices, cullcount); } } for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { if (cullcount >= p_max_results) break; if (E->key()->pass == pass) continue; E->key()->pass = pass; if (!p_aabb.intersects(E->key()->aabb)) continue; /* if (!E->key()->aabb.intersects_segment(p_from,p_to)) continue; */ p_results[cullcount] = E->key()->owner; p_result_indices[cullcount] = E->key()->subindex; cullcount++; } return cullcount; }
void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const { //tiling not supported for this if (p_src_rect.size.x==0 || p_src_rect.size.y==0) return; Size2 scale = p_rect.size/p_src_rect.size; for(int i=0;i<pieces.size();i++) { // TODO Rect2 rect( pieces[i].offset, pieces[i].texture->get_size()); if (!p_src_rect.intersects(rect)) continue; Rect2 local = p_src_rect.clip(rect); Rect2 target = local; target.size*=scale; target.pos=p_rect.pos+(p_src_rect.pos+rect.pos)*scale; local.pos-=rect.pos; pieces[i].texture->draw_rect_region(p_canvas_item,target,local,p_modulate,p_transpose); } }
void BroadPhase2DHashGrid::_cull(const Point2i p_cell,const Rect2& p_aabb,const Point2& p_from, const Point2& p_to,CollisionObject2DSW** p_results,int p_max_results,int *p_result_indices,int &index) { PosKey pk; pk.x=p_cell.x; pk.y=p_cell.y; uint32_t idx = pk.hash() % hash_table_size; PosBin *pb = hash_table[idx]; while (pb) { if (pb->key == pk) { break; } pb=pb->next; } if (!pb) return; for(Map<Element*,RC>::Element *E=pb->object_set.front();E;E=E->next()) { if (index>=p_max_results) break; if (E->key()->pass==pass) continue; E->key()->pass=pass; if (use_aabb && !p_aabb.intersects(E->key()->aabb)) continue; if (use_segment && !E->key()->aabb.intersects_segment(p_from,p_to)) continue; p_results[index]=E->key()->owner; p_result_indices[index]=E->key()->subindex; index++; } for(Map<Element*,RC>::Element *E=pb->static_object_set.front();E;E=E->next()) { if (index>=p_max_results) break; if (E->key()->pass==pass) continue; if (use_aabb && !p_aabb.intersects(E->key()->aabb)) { continue; } if (use_segment && !E->key()->aabb.intersects_segment(p_from,p_to)) continue; E->key()->pass=pass; p_results[index]=E->key()->owner; p_result_indices[index]=E->key()->subindex; index++; } }
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); } }
void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseMotion> mm = p_ev; if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x); v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y); } if (mm.is_valid() && dragging) { just_selected = true; // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats //drag_accum+=Vector2(mm->get_relative().x,mm->get_relative().y); drag_accum = get_local_mouse_position() - drag_origin; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn && gn->is_selected()) { Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom; if (is_using_snap()) { int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } gn->set_offset(pos); } } } if (mm.is_valid() && box_selecting) { box_selecting_to = get_local_mouse_position(); box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x), MIN(box_selecting_from.y, box_selecting_to.y), ABS(box_selecting_from.x - box_selecting_to.x), ABS(box_selecting_from.y - box_selecting_to.y)); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; Rect2 r = gn->get_rect(); r.size *= zoom; bool in_box = r.intersects(box_selecting_rect); if (in_box) gn->set_selected(box_selection_mode_aditive); else gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } Ref<InputEventMouseButton> b = p_ev; if (b.is_valid()) { if (b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { if (box_selecting) { box_selecting = false; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } else { if (connecting) { connecting = false; top_layer->update(); } else { emit_signal("popup_request", b->get_global_position()); } } } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) { if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn) { Rect2 r = gn->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_position())) gn->set_selected(false); } } } if (drag_accum != Vector2()) { emit_signal("_begin_node_move"); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (gn && gn->is_selected()) gn->set_drag(false); } emit_signal("_end_node_move"); } dragging = false; top_layer->update(); update(); connections_layer->update(); } if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { GraphNode *gn = NULL; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn_selected = Object::cast_to<GraphNode>(get_child(i)); if (gn_selected) { if (gn_selected->is_resizing()) continue; if (gn_selected->has_point(gn_selected->get_local_mouse_position())) { gn = gn_selected; break; } } } if (gn) { if (_filter_input(b->get_position())) return; dragging = true; drag_accum = Vector2(); drag_origin = get_local_mouse_position(); just_selected = !gn->is_selected(); if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (o_gn) o_gn->set_selected(o_gn == gn); } } gn->set_selected(true); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (!o_gn) continue; if (o_gn->is_selected()) o_gn->set_drag(true); } } else { if (_filter_input(b->get_position())) return; if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; box_selecting_from = get_local_mouse_position(); if (b->get_control()) { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2 || !gn2->is_selected()) continue; previus_selected.push_back(gn2); } } else if (b->get_shift()) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2 || !gn2->is_selected()) continue; previus_selected.push_back(gn2); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2) continue; gn2->set_selected(false); } } } } if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && box_selecting) { box_selecting = false; previus_selected.clear(); top_layer->update(); } if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) { //too difficult to get right //set_zoom(zoom*ZOOM_SCALE); } if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8); } if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8); } } Ref<InputEventKey> k = p_ev; if (k.is_valid() && k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) { emit_signal("duplicate_nodes_request"); accept_event(); } if (k.is_valid() && k->get_scancode() == KEY_DELETE && k->is_pressed()) { emit_signal("delete_nodes_request"); accept_event(); } Ref<InputEventMagnifyGesture> magnify_gesture = p_ev; if (magnify_gesture.is_valid()) { set_zoom_custom(zoom * magnify_gesture->get_factor(), magnify_gesture->get_position()); } Ref<InputEventPanGesture> pan_gesture = p_ev; if (pan_gesture.is_valid()) { h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8); v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8); } }
void ConcavePolygonShape2DSW::cull(const Rect2& p_local_aabb,Callback p_callback,void* p_userdata) const { uint32_t* stack = (uint32_t*)alloca(sizeof(int)*bvh_depth); enum { TEST_AABB_BIT=0, VISIT_LEFT_BIT=1, VISIT_RIGHT_BIT=2, VISIT_DONE_BIT=3, VISITED_BIT_SHIFT=29, NODE_IDX_MASK=(1<<VISITED_BIT_SHIFT)-1, VISITED_BIT_MASK=~NODE_IDX_MASK, }; //for(int i=0;i<bvh_depth;i++) // stack[i]=0; int level=0; const Segment *segmentptr=&segments[0]; const Vector2 *pointptr=&points[0]; const BVH *bvhptr = &bvh[0]; int pos=bvh.size()-1; stack[0]=0; while(true) { uint32_t node = stack[level]&NODE_IDX_MASK; const BVH &b = bvhptr[ node ]; switch(stack[level]>>VISITED_BIT_SHIFT) { case TEST_AABB_BIT: { bool valid = p_local_aabb.intersects(b.aabb); if (!valid) { stack[level]=(VISIT_DONE_BIT<<VISITED_BIT_SHIFT)|node; } else { if (b.left<0) { const Segment &s=segmentptr[ b.right ]; Vector2 a = pointptr[ s.points[0] ]; Vector2 b = pointptr[ s.points[1] ]; SegmentShape2DSW ss(a,b,(b-a).tangent().normalized()); p_callback(p_userdata,&ss); stack[level]=(VISIT_DONE_BIT<<VISITED_BIT_SHIFT)|node; } else { stack[level]=(VISIT_LEFT_BIT<<VISITED_BIT_SHIFT)|node; } } } continue; case VISIT_LEFT_BIT: { stack[level]=(VISIT_RIGHT_BIT<<VISITED_BIT_SHIFT)|node; stack[level+1]=b.left|TEST_AABB_BIT; level++; } continue; case VISIT_RIGHT_BIT: { stack[level]=(VISIT_DONE_BIT<<VISITED_BIT_SHIFT)|node; stack[level+1]=b.right|TEST_AABB_BIT; level++; } continue; case VISIT_DONE_BIT: { if (level==0) return; else level--; } continue; } } }
void GraphEdit::_gui_input(const InputEvent &p_ev) { if (p_ev.type == InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask & BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_value(h_scroll->get_value() - p_ev.mouse_motion.relative_x); v_scroll->set_value(v_scroll->get_value() - p_ev.mouse_motion.relative_y); } if (p_ev.type == InputEvent::MOUSE_MOTION && dragging) { just_selected = true; // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats //drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); drag_accum = get_local_mouse_pos() - drag_origin; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn && gn->is_selected()) { Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom; if (is_using_snap()) { int snap = get_snap(); pos = pos.snapped(Vector2(snap, snap)); } gn->set_offset(pos); } } } if (p_ev.type == InputEvent::MOUSE_MOTION && box_selecting) { box_selecting_to = get_local_mouse_pos(); box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x), MIN(box_selecting_from.y, box_selecting_to.y), ABS(box_selecting_from.x - box_selecting_to.x), ABS(box_selecting_from.y - box_selecting_to.y)); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; Rect2 r = gn->get_rect(); r.size *= zoom; bool in_box = r.intersects(box_selecting_rect); if (in_box) gn->set_selected(box_selection_mode_aditive); else gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } if (p_ev.type == InputEvent::MOUSE_BUTTON) { const InputEventMouseButton &b = p_ev.mouse_button; if (b.button_index == BUTTON_RIGHT && b.pressed) { if (box_selecting) { box_selecting = false; for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; gn->set_selected(previus_selected.find(gn) != NULL); } top_layer->update(); } else { if (connecting) { connecting = false; top_layer->update(); } else { emit_signal("popup_request", Vector2(b.global_x, b.global_y)); } } } if (b.button_index == BUTTON_LEFT && !b.pressed && dragging) { if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { //deselect current node for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn) { Rect2 r = gn->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_pos())) gn->set_selected(false); } } } if (drag_accum != Vector2()) { emit_signal("_begin_node_move"); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (gn && gn->is_selected()) gn->set_drag(false); } emit_signal("_end_node_move"); } dragging = false; top_layer->update(); update(); connections_layer->update(); } if (b.button_index == BUTTON_LEFT && b.pressed) { GraphNode *gn = NULL; GraphNode *gn_selected = NULL; for (int i = get_child_count() - 1; i >= 0; i--) { gn_selected = get_child(i)->cast_to<GraphNode>(); if (gn_selected) { if (gn_selected->is_resizing()) continue; Rect2 r = gn_selected->get_rect(); r.size *= zoom; if (r.has_point(get_local_mouse_pos())) gn = gn_selected; break; } } if (gn) { if (_filter_input(Vector2(b.x, b.y))) return; dragging = true; drag_accum = Vector2(); drag_origin = get_local_mouse_pos(); just_selected = !gn->is_selected(); if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = get_child(i)->cast_to<GraphNode>(); if (o_gn) o_gn->set_selected(o_gn == gn); } } gn->set_selected(true); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = get_child(i)->cast_to<GraphNode>(); if (!o_gn) continue; if (o_gn->is_selected()) o_gn->set_drag(true); } } else { if (_filter_input(Vector2(b.x, b.y))) return; if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) return; box_selecting = true; box_selecting_from = get_local_mouse_pos(); if (b.mod.control) { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn || !gn->is_selected()) continue; previus_selected.push_back(gn); } } else if (b.mod.shift) { box_selection_mode_aditive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn || !gn->is_selected()) continue; previus_selected.push_back(gn); } } else { box_selection_mode_aditive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = get_child(i)->cast_to<GraphNode>(); if (!gn) continue; gn->set_selected(false); } } } } if (b.button_index == BUTTON_LEFT && !b.pressed && box_selecting) { box_selecting = false; previus_selected.clear(); top_layer->update(); } if (b.button_index == BUTTON_WHEEL_UP && b.pressed) { //too difficult to get right //set_zoom(zoom*ZOOM_SCALE); } if (b.button_index == BUTTON_WHEEL_DOWN && b.pressed) { //too difficult to get right //set_zoom(zoom/ZOOM_SCALE); } } if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_D && p_ev.key.pressed && p_ev.key.mod.command) { emit_signal("duplicate_nodes_request"); accept_event(); } if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_DELETE && p_ev.key.pressed) { emit_signal("delete_nodes_request"); accept_event(); } }