void ControlEditor::_find_controls_span(Node *p_node, Rect2& r_rect) { if (!editor->get_scene()) return; if (p_node!=editor->get_edited_scene() && p_node->get_owner()!=editor->get_edited_scene()) return; if (p_node->cast_to<Control>()) { Control *c = p_node->cast_to<Control>(); if (c->get_viewport() != editor->get_viewport()->get_viewport()) return; //bye, it's in another viewport if (!c->get_parent_control()) { Rect2 span = c->get_subtree_span_rect(); r_rect.merge(span); } } for(int i=0;i<p_node->get_child_count();i++) { _find_controls_span(p_node->get_child(i),r_rect); } }
void Particles2DEditorPlugin::_generate_visibility_rect() { float time = generate_seconds->get_value(); float running = 0.0; EditorProgress ep("gen_aabb", TTR("Generating AABB"), int(time)); Rect2 rect; while (running < time) { uint64_t ticks = OS::get_singleton()->get_ticks_usec(); ep.step("Generating..", int(running), true); OS::get_singleton()->delay_usec(1000); Rect2 capture = particles->capture_rect(); if (rect == Rect2()) rect = capture; else rect = rect.merge(capture); running += (OS::get_singleton()->get_ticks_usec() - ticks) / 1000000.0; } particles->set_visibility_rect(rect); }
bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,ShapeRestInfo *r_info, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape,0); Rect2 aabb = p_shape_xform.xform(shape->get_aabb()); aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion aabb=aabb.grow(p_margin); int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); _RestCallbackData rcd; rcd.best_len=0; rcd.best_object=NULL; rcd.best_shape=0; for(int i=0;i<amount;i++) { if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask)) continue; const CollisionObject2DSW *col_obj=space->intersection_query_results[i]; int shape_idx=space->intersection_query_subindex_results[i]; if (p_exclude.has( col_obj->get_self() )) continue; rcd.object=col_obj; rcd.shape=shape_idx; bool sc = CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2() ,_rest_cbk_result,&rcd,NULL,p_margin); if (!sc) continue; } if (rcd.best_len==0) return false; r_info->collider_id=rcd.best_object->get_instance_id(); r_info->shape=rcd.best_shape; r_info->normal=rcd.best_normal; r_info->point=rcd.best_contact; r_info->rid=rcd.best_object->get_self(); if (rcd.best_object->get_type()==CollisionObject2DSW::TYPE_BODY) { const Body2DSW *body = static_cast<const Body2DSW*>(rcd.best_object); Vector2 rel_vec = r_info->point-body->get_transform().get_origin(); r_info->linear_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity(); } else { r_info->linear_velocity=Vector2(); } return true; }
bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,float p_margin,Vector2 *r_results,int p_result_max,int &r_result_count, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { if (p_result_max<=0) return 0; Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape,0); Rect2 aabb = p_shape_xform.xform(shape->get_aabb()); aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion aabb=aabb.grow(p_margin); int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); bool collided=false; int cc=0; r_result_count=0; Physics2DServerSW::CollCbkData cbk; cbk.max=p_result_max; cbk.amount=0; cbk.ptr=r_results; CollisionSolver2DSW::CallbackResult cbkres=NULL; Physics2DServerSW::CollCbkData *cbkptr=NULL; if (p_result_max>0) { cbkptr=&cbk; cbkres=Physics2DServerSW::_shape_col_cbk; } for(int i=0;i<amount;i++) { if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask)) continue; const CollisionObject2DSW *col_obj=space->intersection_query_results[i]; int shape_idx=space->intersection_query_subindex_results[i]; if (p_exclude.has( col_obj->get_self() )) continue; if (CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),cbkres,cbkptr,NULL,p_margin)) { collided=true; } } r_result_count=cbk.amount; return collided; }
void GraphEdit::_update_scroll() { if (updating) return; updating = true; set_block_minimum_size_adjust(true); Rect2 screen; for (int i = 0; i < get_child_count(); i++) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); if (!gn) continue; Rect2 r; r.position = gn->get_offset() * zoom; r.size = gn->get_size() * zoom; screen = screen.merge(r); } screen.position -= get_size(); screen.size += get_size() * 2.0; h_scroll->set_min(screen.position.x); h_scroll->set_max(screen.position.x + screen.size.x); h_scroll->set_page(get_size().x); if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page()) h_scroll->hide(); else h_scroll->show(); v_scroll->set_min(screen.position.y); v_scroll->set_max(screen.position.y + screen.size.y); v_scroll->set_page(get_size().y); if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page()) v_scroll->hide(); else v_scroll->show(); set_block_minimum_size_adjust(false); if (!awaiting_scroll_offset_update) { call_deferred("_update_scroll_offset"); awaiting_scroll_offset_update = true; } updating = false; }
Rect2 CanvasItem::_edit_get_item_and_children_rect() const { Rect2 rect = _edit_get_rect(); for (int i = 0; i < get_child_count(); i++) { CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i)); if (c) { Rect2 sir = c->get_transform().xform(c->_edit_get_item_and_children_rect()); rect = rect.merge(sir); } } return rect; }
void GraphEdit::_update_scroll() { if (updating) return; updating=true; Rect2 screen; for(int i=0;i<get_child_count();i++) { GraphNode *gn=get_child(i)->cast_to<GraphNode>(); if (!gn) continue; Rect2 r; r.pos=gn->get_offset(); r.size=gn->get_size(); screen = screen.merge(r); } screen.pos-=get_size(); screen.size+=get_size()*2.0; h_scroll->set_min(screen.pos.x); h_scroll->set_max(screen.pos.x+screen.size.x); h_scroll->set_page(get_size().x); if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page()) h_scroll->hide(); else h_scroll->show(); v_scroll->set_min(screen.pos.y); v_scroll->set_max(screen.pos.y+screen.size.y); v_scroll->set_page(get_size().y); if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page()) v_scroll->hide(); else v_scroll->show(); _update_scroll_offset(); updating=false; }
void Particles2DEditorPlugin::_generate_visibility_rect() { float time = generate_seconds->get_value(); float running = 0.0; EditorProgress ep("gen_vrect", TTR("Generating Visibility Rect"), int(time)); bool was_emitting = particles->is_emitting(); if (!was_emitting) { particles->set_emitting(true); OS::get_singleton()->delay_usec(1000); } Rect2 rect; while (running < time) { uint64_t ticks = OS::get_singleton()->get_ticks_usec(); ep.step("Generating...", int(running), true); OS::get_singleton()->delay_usec(1000); Rect2 capture = particles->capture_rect(); if (rect == Rect2()) rect = capture; else rect = rect.merge(capture); running += (OS::get_singleton()->get_ticks_usec() - ticks) / 1000000.0; } if (!was_emitting) { particles->set_emitting(false); } undo_redo->create_action(TTR("Generate Visibility Rect")); undo_redo->add_do_method(particles, "set_visibility_rect", rect); undo_redo->add_undo_method(particles, "set_visibility_rect", particles->get_visibility_rect()); undo_redo->commit_action(); }
bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape,false); Rect2 aabb = p_xform.xform(shape->get_aabb()); aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion aabb=aabb.grow(p_margin); //if (p_motion!=Vector2()) // print_line(p_motion); int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); float best_safe=1; float best_unsafe=1; for(int i=0; i<amount; i++) { if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask)) continue; if (p_exclude.has( space->intersection_query_results[i]->get_self())) continue; //ignore excluded const CollisionObject2DSW *col_obj=space->intersection_query_results[i]; int shape_idx=space->intersection_query_subindex_results[i]; /*if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) { const Body2DSW *body=static_cast<const Body2DSW*>(col_obj); if (body->get_one_way_collision_direction()!=Vector2() && p_motion.dot(body->get_one_way_collision_direction())<=CMP_EPSILON) { print_line("failed in motion dir"); continue; } }*/ Matrix32 col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) { continue; } //test initial overlap if (CollisionSolver2DSW::solve(shape,p_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) { if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) { //if one way collision direction ignore initial overlap const Body2DSW *body=static_cast<const Body2DSW*>(col_obj); if (body->get_one_way_collision_direction()!=Vector2()) { continue; } } return false; } //just do kinematic solving float low=0; float hi=1; Vector2 mnormal=p_motion.normalized(); for(int i=0; i<8; i++) { //steps should be customizable.. Matrix32 xfa = p_xform; float ofs = (low+hi)*0.5; Vector2 sep=mnormal; //important optimization for this to work fast enough bool collided = CollisionSolver2DSW::solve(shape,p_xform,p_motion*ofs,col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),NULL,NULL,&sep,p_margin); if (collided) { hi=ofs; } else { low=ofs; } } if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) { const Body2DSW *body=static_cast<const Body2DSW*>(col_obj); if (body->get_one_way_collision_direction()!=Vector2()) { Vector2 cd[2]; Physics2DServerSW::CollCbkData cbk; cbk.max=1; cbk.amount=0; cbk.ptr=cd; cbk.valid_dir=body->get_one_way_collision_direction(); cbk.valid_depth=body->get_one_way_collision_max_depth(); Vector2 sep=mnormal; //important optimization for this to work fast enough bool collided = CollisionSolver2DSW::solve(shape,p_xform,p_motion*(hi+space->contact_max_allowed_penetration),col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),Physics2DServerSW::_shape_col_cbk,&cbk,&sep,p_margin); if (!collided || cbk.amount==0) { continue; } } } if (low<best_safe) { best_safe=low; best_unsafe=hi; } } p_closest_safe=best_safe; p_closest_unsafe=best_unsafe; return true; }
bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) { Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, false); Rect2 aabb = p_xform.xform(shape->get_aabb()); aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); /* if (p_motion!=Vector2()) print_line(p_motion); */ int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); real_t best_safe = 1; real_t best_unsafe = 1; for (int i = 0; i < amount; i++) { if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask)) continue; if (p_exclude.has(space->intersection_query_results[i]->get_self())) continue; //ignore excluded const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; /*if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) { const Body2DSW *body=static_cast<const Body2DSW*>(col_obj); if (body->get_one_way_collision_direction()!=Vector2() && p_motion.dot(body->get_one_way_collision_direction())<=CMP_EPSILON) { print_line("failed in motion dir"); continue; } }*/ Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) { continue; } //test initial overlap if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) { return false; } //just do kinematic solving real_t low = 0; real_t hi = 1; Vector2 mnormal = p_motion.normalized(); for (int i = 0; i < 8; i++) { //steps should be customizable.. real_t ofs = (low + hi) * 0.5; Vector2 sep = mnormal; //important optimization for this to work fast enough bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, &sep, p_margin); if (collided) { hi = ofs; } else { low = ofs; } } if (low < best_safe) { best_safe = low; best_unsafe = hi; } } p_closest_safe = best_safe; p_closest_unsafe = best_unsafe; return true; }
bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion, MotionCastCollision &r_result, const Set<RID>& p_exclude,uint32_t p_user_mask) { Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape,0); Rect2 aabb = p_xform.xform(shape->get_aabb()); aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); bool collided=false; r_result.travel=1; MotionCallbackRayCastData best_normal; best_normal.best_len=1e20; for(int i=0;i<amount;i++) { if (space->intersection_query_results[i]->get_type()==CollisionObject2DSW::TYPE_AREA) continue; //ignore area if (p_exclude.has( space->intersection_query_results[i]->get_self())) continue; //ignore excluded const CollisionObject2DSW *col_obj=space->intersection_query_results[i]; int shape_idx=space->intersection_query_subindex_results[i]; Matrix32 col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL)) { continue; } //test initial overlap if (CollisionSolver2DSW::solve(shape,p_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL)) { r_result.collider_id=col_obj->get_instance_id(); r_result.collider=r_result.collider_id!=0 ? ObjectDB::get_instance(col_obj->get_instance_id()) : NULL; r_result.shape=shape_idx; r_result.rid=col_obj->get_self(); r_result.travel=0; r_result.point=Vector2(); r_result.normal=Vector2(); return true; } #if 0 Vector2 mnormal=p_motion.normalized(); Matrix32 col_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); ShapeSW *col_shape = col_obj->get_shape(shape_idx); real_t min,max; col_shape->project_rangev(mnormal,col_shape_xform,min,max); real_t width = max-min; int a; Vector2 s[2]; col_shape->get_supports(col_shape_xform.basis_xform(mnormal).normalized(),s,a); Vector2 from = col_shape_xform.xform(s[0]); Vector2 to = from + p_motion; Matrix32 from_inv = col_shape_xform.affine_inverse(); Vector2 local_from = from_inv.xform(from-mnormal*width*0.1); //start from a little inside the bounding box Vector2 local_to = from_inv.xform(to); Vector2 rpos,rnorm; if (!col_shape->intersect_segment(local_from,local_to,rpos,rnorm)) return false; //ray hit something Vector2 hitpos = p_xform_B.xform(rpos); #endif //just do kinematic solving float low=0; float hi=1; Vector2 mnormal=p_motion.normalized(); for(int i=0;i<8;i++) { //steps should be customizable.. Matrix32 xfa = p_xform; float ofs = (low+hi)*0.5; Vector2 sep=mnormal; //important optimization for this to work fast enough bool collided = CollisionSolver2DSW::solve(shape,p_xform,p_motion*ofs,col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),NULL,NULL,&sep); if (collided) { hi=ofs; } else { low=ofs; } } best_normal.shape_B=col_obj->get_shape(shape_idx); best_normal.motion=p_motion*hi; best_normal.b_xform=col_obj_xform; best_normal.b_xform_inv=col_obj_xform.affine_inverse(); bool sc = CollisionSolver2DSW::solve(shape,p_xform,p_motion*hi,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2() ,_motion_cbk_result,&best_normal); print_line("CLD: "+itos(sc)); if (collided && low>=r_result.travel) continue; collided=true; r_result.travel=low; r_result.collider_id=col_obj->get_instance_id(); r_result.collider=r_result.collider_id!=0 ? ObjectDB::get_instance(col_obj->get_instance_id()) : NULL; r_result.shape=shape_idx; r_result.rid=col_obj->get_self(); } if (collided) { ERR_FAIL_COND_V(best_normal.best_normal==Vector2(),false); r_result.normal=best_normal.best_normal; r_result.point=best_normal.best_contact; } return collided; }
bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) { Shape2DSW *shape = static_cast<Physics2DServerSW*>(Physics2DServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape,false); Rect2 aabb = p_xform.xform(shape->get_aabb()); aabb=aabb.merge(Rect2(aabb.pos+p_motion,aabb.size)); //motion aabb=aabb.grow(p_margin); //if (p_motion!=Vector2()) // print_line(p_motion); int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); float best_safe=1; float best_unsafe=1; for(int i=0;i<amount;i++) { if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask)) continue; if (p_exclude.has( space->intersection_query_results[i]->get_self())) continue; //ignore excluded const CollisionObject2DSW *col_obj=space->intersection_query_results[i]; int shape_idx=space->intersection_query_subindex_results[i]; Matrix32 col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); //test initial overlap, does it collide if going all the way? if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) { continue; } //test initial overlap if (CollisionSolver2DSW::solve(shape,p_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) { return false; } //just do kinematic solving float low=0; float hi=1; Vector2 mnormal=p_motion.normalized(); for(int i=0;i<8;i++) { //steps should be customizable.. Matrix32 xfa = p_xform; float ofs = (low+hi)*0.5; Vector2 sep=mnormal; //important optimization for this to work fast enough bool collided = CollisionSolver2DSW::solve(shape,p_xform,p_motion*ofs,col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),NULL,NULL,&sep,p_margin); if (collided) { hi=ofs; } else { low=ofs; } } if (low<best_safe) { best_safe=low; best_unsafe=hi; } } p_closest_safe=best_safe; p_closest_unsafe=best_unsafe; return true; }