Exemple #1
0
int ItemList::get_item_at_pos(const Point2& p_pos) const {

	Vector2 pos=p_pos;
	Ref<StyleBox> bg = get_stylebox("bg");
	pos-=bg->get_offset();
	pos.y+=scroll_bar->get_val();

	int closest = -1;
	int closest_dist=0x7FFFFFFF;

	for(int i=0;i<items.size();i++) {

		Rect2 rc = items[i].rect_cache;
		if (i%current_columns==current_columns-1) {
			rc.size.width=get_size().width; //not right but works
		}

		if (rc.has_point(pos)) {
			closest=i;
			break;
		}

		float dist = rc.distance_to(pos);
		if (dist<closest_dist) {
			closest=i;
			closest_dist=dist;
		}
	}

	return closest;
}
Exemple #2
0
bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos) {
	if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos))
		return false;

	for (int i = 0; i < get_child_count(); i++) {
		Control *child = Object::cast_to<Control>(get_child(i));
		if (!child)
			continue;
		Rect2 rect = child->get_rect();
		if (rect.has_point(p_mouse_pos)) {

			//check sub-controls
			Vector2 subpos = p_mouse_pos - rect.position;

			for (int j = 0; j < child->get_child_count(); j++) {
				Control *subchild = Object::cast_to<Control>(child->get_child(j));
				if (!subchild)
					continue;

				if (_check_clickable_control(subchild, subpos - subchild->get_position())) {
					return false;
				}
			}
		}
	}

	return true;
}
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);
}
Exemple #4
0
void GraphEdit::_draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color) {

	static const int steps = 20;

	Rect2 r;
	r.pos=p_from;
	r.expand_to(p_to);
	Vector2 sign=Vector2((p_from.x < p_to.x) ? 1 : -1,(p_from.y < p_to.y) ? 1 : -1);
	bool flip = sign.x * sign.y < 0;

	Vector2 prev;
	for(int i=0;i<=steps;i++) {

		float d = i/float(steps);
		float c=-Math::cos(d*Math_PI) * 0.5+0.5;
		if (flip)
			c=1.0-c;
		Vector2 p = r.pos+Vector2(d*r.size.width,c*r.size.height);

		if (i>0) {

			top_layer->draw_line(prev,p,p_color,2);
		}

		prev=p;
	}
}
void TileMapEditor::_update_palette() {

	if (!node)
		return;

	int selected = get_selected_tile();
	palette->clear();

	Ref<TileSet> tileset=node->get_tileset();
	if (tileset.is_null())
		return;

	List<int> tiles;
	tileset->get_tile_list(&tiles);

	if (tiles.empty())
		return;

	palette->set_max_columns(0);
	palette->set_icon_mode(ItemList::ICON_MODE_TOP);
	palette->set_max_text_lines(2);

	String filter = search_box->get_text().strip_edges();

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

		String name;

		if (tileset->tile_get_name(E->get())!="") {
			name = tileset->tile_get_name(E->get());
		} else {
			name = "#"+itos(E->get());
		}

		if (filter != "" && name.findn(filter) == -1)
			continue;

		palette->add_item(name);

		Ref<Texture> tex = tileset->tile_get_texture(E->get());

		if (tex.is_valid()) {
			Rect2 region = tileset->tile_get_region(E->get());

			if (!region.has_no_area())
				palette->set_item_icon_region(palette->get_item_count()-1, region);

			palette->set_item_icon(palette->get_item_count()-1, tex);
		}

		palette->set_item_metadata(palette->get_item_count()-1, E->get());
	}

	if (selected != -1)
		set_selected_tile(selected);
	else
		palette->select(0, true);
}
Exemple #6
0
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;
}
Exemple #7
0
void ConvexPolygonShape2DSW::set_data(const Variant& p_data) {

	ERR_FAIL_COND(p_data.get_type()!=Variant::VECTOR2_ARRAY && p_data.get_type()!=Variant::REAL_ARRAY);


	if (points)
		memdelete_arr(points);
	points=NULL;
	point_count=0;

	if (p_data.get_type()==Variant::VECTOR2_ARRAY) {
		DVector<Vector2> arr=p_data;
		ERR_FAIL_COND(arr.size()==0);
		point_count=arr.size();
		points = memnew_arr(Point,point_count);
		DVector<Vector2>::Read r = arr.read();

		for(int i=0;i<point_count;i++) {
			points[i].pos=r[i];
		}

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

			Vector2 p = points[i].pos;
			Vector2 pn = points[(i+1)%point_count].pos;
			points[i].normal=(pn-p).tangent().normalized();
		}
	} else {

		DVector<real_t> dvr = p_data;
		point_count=dvr.size()/4;
		ERR_FAIL_COND(point_count==0);

		points = memnew_arr(Point,point_count);
		DVector<real_t>::Read r = dvr.read();

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

			int idx=i<<2;
			points[i].pos.x=r[idx+0];
			points[i].pos.y=r[idx+1];
			points[i].normal.x=r[idx+2];
			points[i].normal.y=r[idx+3];

		}
	}


	ERR_FAIL_COND(point_count==0);
	Rect2 aabb;
	aabb.pos=points[0].pos;
	for(int i=1;i<point_count;i++)
		aabb.expand_to(points[i].pos);

	configure(aabb);
}
void handleMouse(const Rect2& view, int viewportWidth, int viewportHeight)
{
  int x, y;
  ubyte state = SDL_GetMouseState(&x, &y);
  real vx = x;
  real vy = viewportHeight-y;
  gMouseX = (vx/viewportWidth)*view.width()+view.left();
  gMouseY = (vy/viewportHeight)*view.height()+view.bottom();         
  gMouseButton = state & SDL_BUTTON(1);    
}
Exemple #9
0
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(float p_mass) const {

	Rect2 aabb;
	aabb.pos=points[0].pos;
	for(int i=0;i<point_count;i++) {

		aabb.expand_to(points[i].pos);
	}

	return p_mass*aabb.size.dot(aabb.size)/12.0f;
}
Exemple #10
0
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;
}
Exemple #11
0
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(float p_mass,const Vector2& p_scale) const {

	Rect2 aabb;
	aabb.pos=points[0].pos*p_scale;
	for(int i=0;i<point_count;i++) {

		aabb.expand_to(points[i].pos*p_scale);
	}

	return p_mass*aabb.size.dot(aabb.size)/12.0f + p_mass * (aabb.pos+aabb.size*0.5).length_squared();
}
Exemple #12
0
Rect2 Line2D::_edit_get_rect() const {

	if (_points.size() == 0)
		return Rect2(0, 0, 0, 0);
	Vector2 d = Vector2(_width, _width);
	Rect2 aabb = Rect2(_points[0] - d, 2 * d);
	for (int i = 1; i < _points.size(); i++) {
		aabb.expand_to(_points[i] - d);
		aabb.expand_to(_points[i] + d);
	}
	return aabb;
}
Rect2 ConvexPolygonShape2D::get_rect() const {

	Rect2 rect;
	for (int i = 0; i < points.size(); i++) {
		if (i == 0)
			rect.position = points[i];
		else
			rect.expand_to(points[i]);
	}

	return rect;
}
void TileMapEditor::_update_palette() {

	if (!node)
		return;

	palette->clear();

	Ref<TileSet> tileset=node->get_tileset();
	if (!tileset.is_valid())
		return;

	List<int> tiles;
	tileset->get_tile_list(&tiles);

	if (display_mode == DISPLAY_THUMBNAIL) {
		palette->set_max_columns(0);
		palette->set_icon_mode(ItemList::ICON_MODE_TOP);
	} else if (display_mode == DISPLAY_LIST) {
		palette->set_max_columns(1);
		palette->set_icon_mode(ItemList::ICON_MODE_LEFT);
	}

	palette->set_max_text_lines(2);

	for(List<int>::Element *E=tiles.front();E;E=E->next()) {
		palette->add_item("");

		Ref<Texture> tex = tileset->tile_get_texture(E->get());

		if (tex.is_valid()) {
			Rect2 region = tileset->tile_get_region(E->get());

			if (!region.has_no_area()) {
				Image data = VS::get_singleton()->texture_get_data(tex->get_rid());

				Ref<ImageTexture> img = memnew( ImageTexture );
				img->create_from_image(data.get_rect(region));

				palette->set_item_icon(palette->get_item_count()-1, img);
			} else {
				palette->set_item_icon(palette->get_item_count()-1,tex);
			}
		}

		if (tileset->tile_get_name(E->get())!="") {
			palette->set_item_text(palette->get_item_count()-1, tileset->tile_get_name(E->get()));
		} else {
			palette->set_item_text(palette->get_item_count()-1, "#"+itos(E->get()));
		}

		palette->set_item_metadata(palette->get_item_count()-1, E->get());
	}
}
Exemple #15
0
Rect2 LineShape2D::get_rect() const {

	Vector2 point = get_d() * get_normal();

	Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
	Vector2 l2[2] = { point, point + get_normal() * 30 };
	Rect2 rect;
	rect.pos = l1[0];
	rect.expand_to(l1[1]);
	rect.expand_to(l2[0]);
	rect.expand_to(l2[1]);
	return rect;
}
Exemple #16
0
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;
}
Exemple #17
0
void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color) {

#if 1

	//cubic bezier code
	float diff = p_to.x - p_from.x;
	float cp_offset;
	int cp_len = get_constant("bezier_len_pos");
	int cp_neg_len = get_constant("bezier_len_neg");

	if (diff > 0) {
		cp_offset = MAX(cp_len, diff * 0.5);
	} else {
		cp_offset = MAX(MIN(cp_len - diff, cp_neg_len), -diff * 0.5);
	}

	Vector2 c1 = Vector2(cp_offset * zoom, 0);
	Vector2 c2 = Vector2(-cp_offset * zoom, 0);

	int lines = 0;
	_bake_segment2d(p_where, 0, 1, p_from, c1, p_to, c2, 0, 3, 9, 8, p_color, p_to_color, lines);

#else

	static const int steps = 20;

	//old cosine code
	Rect2 r;
	r.pos = p_from;
	r.expand_to(p_to);
	Vector2 sign = Vector2((p_from.x < p_to.x) ? 1 : -1, (p_from.y < p_to.y) ? 1 : -1);
	bool flip = sign.x * sign.y < 0;

	Vector2 prev;
	for (int i = 0; i <= steps; i++) {

		float d = i / float(steps);
		float c = -Math::cos(d * Math_PI) * 0.5 + 0.5;
		if (flip)
			c = 1.0 - c;
		Vector2 p = r.pos + Vector2(d * r.size.width, c * r.size.height);

		if (i > 0) {

			p_where->draw_line(prev, p, p_color.linear_interpolate(p_to_color, d), 2);
		}

		prev = p;
	}
#endif
}
Exemple #18
0
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;
}
Exemple #19
0
// mesh = m, dir = vector(1, 0, 0)
void Intersector::init()
{
    int i, j, k;
    const vector<MeshVertex> &vtc = mesh->vertices;
    const vector<MeshEdge> &edg = mesh->edges;
    
    dir = dir.normalize();
    getBasis(dir, v1, v2);
	// 建立一个以dir, v1, v2为坐标轴的坐标系
	// dir(1, 0, 0) v1(0, 0, 1) v2(0, -1, 0)
    
    points.resize(vtc.size());
    sNormals.resize(edg.size() / 3);
    for(i = 0; i < (int)vtc.size(); ++i) {
		// *表示内积
        points[i] = Vector2(vtc[i].pos * v1, vtc[i].pos * v2);
    }
    
    bounds = Rect2(points.begin(), points.end());
    
	// points数组存储的是每个顶点在v1和v2方向上的投影,bounds是这些投影的二维包围盒
    triangles.resize(cells * cells);
    for(i = 0; i < (int)edg.size(); i += 3) {
        Rect2 triRect;
        for(j = 0; j < 3; ++j)
            triRect |= Rect2(points[edg[i + j].vertex]);
        
        int fromx, fromy, tox, toy;
        getIndex(triRect.getLo(), fromx, fromy);
        getIndex(triRect.getHi(), tox, toy);
		// 得到的fromx, fromy分别是将bounds分为200*200的网格后,其包围盒左下角在整个网格(bounds)中的x,y方向上的网格索引号
		// tox, toy是三角形包围盒右上角在网格中的索引号
        
        for(j = fromy; j <= toy; ++j) for(k = fromx; k <= tox; ++k) {
            triangles[j * cells + k].push_back(i);
        }
		// triangles中存储的是与这些网格有交点的三角面片
        
        Vector3 cross = (vtc[edg[i + 1].vertex].pos - vtc[edg[i].vertex].pos) % (vtc[edg[i + 2].vertex].pos - vtc[edg[i].vertex].pos);
        j = i / 3;
		// j为面片的索引号
        sNormals[j] = cross.normalize();
        if(fabs(sNormals[j] * dir) <= 1e-8)
            sNormals[j] = Vector3(); //zero if coplanar
        else
            sNormals[j] = sNormals[j] / (sNormals[j] * dir); //prescaled for intersection
		// sNormals[j]为平面的法向在dir方向上的投影
    }
}
Exemple #20
0
int Tabs::get_tab_idx_at_point(const Point2 &p_point) const {

	int hover_now = -1;
	for (int i = 0; i < tabs.size(); i++) {

		if (i < offset)
			continue;

		Rect2 rect = get_tab_rect(i);
		if (rect.has_point(p_point)) {
			hover_now = i;
		}
	}

	return hover_now;
}
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);
	}
}
Exemple #22
0
int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,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_xform.xform(shape->get_aabb());
    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;

    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;


        const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
        int shape_idx=space->intersection_query_subindex_results[i];

        if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),NULL,NULL,NULL,p_margin))
            continue;

        r_results[cc].collider_id=col_obj->get_instance_id();
        if (r_results[cc].collider_id!=0)
            r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
        r_results[cc].rid=col_obj->get_self();
        r_results[cc].shape=shape_idx;
        r_results[cc].metadata=col_obj->get_shape_metadata(shape_idx);

        cc++;

    }

    return cc;

}
Exemple #23
0
void SegmentShape2DSW::set_data(const Variant& p_data) {

	ERR_FAIL_COND(p_data.get_type()!=Variant::RECT2);

	Rect2 r = p_data;
	a=r.pos;
	b=r.size;
	n=(b-a).tangent();

	Rect2 aabb;
	aabb.pos=a;
	aabb.expand_to(b);
	if (aabb.size.x==0)
		aabb.size.x=0.001;
	if (aabb.size.y==0)
		aabb.size.y=0.001;
	configure(aabb);
}
Exemple #24
0
Rect2 Path2D::_edit_get_rect() const {

	if (!curve.is_valid() || curve->get_point_count() == 0)
		return Rect2(0, 0, 0, 0);

	Rect2 aabb = Rect2(curve->get_point_position(0), Vector2(0, 0));

	for (int i = 0; i < curve->get_point_count(); i++) {

		for (int j = 0; j <= 8; j++) {

			real_t frac = j / 8.0;
			Vector2 p = curve->interpolate(i, frac);
			aabb.expand_to(p);
		}
	}

	return aabb;
}
Rect2 ConcavePolygonShape2D::get_rect() const {

	PoolVector<Vector2> s = get_segments();
	int len = s.size();
	if (len == 0)
		return Rect2();

	Rect2 rect;

	PoolVector<Vector2>::Read r = s.read();
	for (int i = 0; i < len; i++) {
		if (i == 0)
			rect.position = r[i];
		else
			rect.expand_to(r[i]);
	}

	return rect;
}
int BroadPhase2DBasic::cull_segment(const Vector2 &p_from, const Vector2 &p_to, 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_segment(p_from, p_to)) {

			p_results[rc] = E->get().owner;
			p_result_indices[rc] = E->get().subindex;
			rc++;
			if (rc >= p_max_results)
				break;
		}
	}

	return rc;
}
Exemple #27
0
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;
}
DVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start) {

	if (node->get_cell(p_start.x, p_start.y) != TileMap::INVALID_CELL)
		return DVector<Vector2>();

	int id = get_selected_tile();

	if (id == TileMap::INVALID_CELL)
		return DVector<Vector2>();

	Rect2 r = node->get_item_rect();
	r.pos = r.pos/node->get_cell_size();
	r.size = r.size/node->get_cell_size();

	DVector<Vector2> points;

	List<Point2i> queue;
	queue.push_back(p_start);

	while (queue.size()) {

		Point2i n = queue.front()->get();
		queue.pop_front();

		if (!r.has_point(n))
			continue;

		if (node->get_cell(n.x, n.y) == TileMap::INVALID_CELL) {

			node->set_cellv(n, id, flip_h, flip_v, transpose);

			points.push_back(n);

			queue.push_back(n + Point2i(0, 1));
			queue.push_back(n + Point2i(0, -1));
			queue.push_back(n + Point2i(1, 0));
			queue.push_back(n + Point2i(-1, 0));
		}
	}

	return points;
}
void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect) {

	if (r_to == r_from)
		return;

	//this could be optimized...
	Vector2 n = (r_to - r_from).normalized();
	while (p_rect.has_point(r_to)) {
		r_to -= n;
	}
}
// slow as hell
Control* ControlEditor::_select_control_at_pos(const Point2& p_pos,Node* p_node) {

	for (int i=p_node->get_child_count()-1;i>=0;i--) {

		Control *r=_select_control_at_pos(p_pos,p_node->get_child(i));
		if (r)
			return r;
	}

	Control *c=p_node->cast_to<Control>();

	if (c) {
		Rect2 rect = c->get_window_rect();
		if (c->get_window()==current_window) {
			rect.pos=transform.xform(rect.pos).floor();
		}
		if (rect.has_point(p_pos))
			return c;
	}

	return NULL;
}