void _ray_query_callback(const RID &p_rid, ObjectID p_id, int p_shape, const Vector2 &p_point, const Vector2 &p_normal) { Vector2 ray_end; if (p_rid.is_valid()) { ray_end = p_point; } else { ray_end = ray_to; } VisualServer *vs = VisualServer::get_singleton(); vs->canvas_item_clear(ray); vs->canvas_item_add_line(ray, ray_from, ray_end, p_rid.is_valid() ? Color(0, 1, 0.4) : Color(1, 0.4, 0), 2); if (p_rid.is_valid()) vs->canvas_item_add_line(ray, ray_end, ray_end + p_normal * 20, p_rid.is_valid() ? Color(0, 1, 0.4) : Color(1, 0.4, 0), 2); }
void _add_concave(const Vector<Vector2> &p_points, const Matrix32 &p_xform = Matrix32()) { Physics2DServer *ps = Physics2DServer::get_singleton(); VisualServer *vs = VisualServer::get_singleton(); RID concave = ps->shape_create(Physics2DServer::SHAPE_CONCAVE_POLYGON); ps->shape_set_data(concave, p_points); RID body = ps->body_create(Physics2DServer::BODY_MODE_STATIC); ps->body_set_space(body, space); ps->body_add_shape(body, concave); ps->body_set_state(body, Physics2DServer::BODY_STATE_TRANSFORM, p_xform); RID sprite = vs->canvas_item_create(); vs->canvas_item_set_parent(sprite, canvas); vs->canvas_item_set_transform(sprite, p_xform); for (int i = 0; i < p_points.size(); i += 2) { vs->canvas_item_add_line(sprite, p_points[i], p_points[i + 1], Color(0, 0, 0), 2); } }
void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { VisualServer *vs = VisualServer::get_singleton(); Rect2i r = p_rect; for (int i = 0; i < border_size; i++) { Color color_upleft = light_color; Color color_downright = dark_color; if (blend) { color_upleft.r = (border_size - i) * color_upleft.r / border_size + i * bg_color.r / border_size; color_upleft.g = (border_size - i) * color_upleft.g / border_size + i * bg_color.g / border_size; color_upleft.b = (border_size - i) * color_upleft.b / border_size + i * bg_color.b / border_size; color_downright.r = (border_size - i) * color_downright.r / border_size + i * bg_color.r / border_size; color_downright.g = (border_size - i) * color_downright.g / border_size + i * bg_color.g / border_size; color_downright.b = (border_size - i) * color_downright.b / border_size + i * bg_color.b / border_size; } vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r.position.x, r.position.y + r.size.y - 1), Size2(r.size.x, 1)), color_downright); vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r.position.x + r.size.x - 1, r.position.y), Size2(1, r.size.y)), color_downright); vs->canvas_item_add_rect(p_canvas_item, Rect2(r.position, Size2(r.size.x, 1)), color_upleft); vs->canvas_item_add_rect(p_canvas_item, Rect2(r.position, Size2(1, r.size.y)), color_upleft); r.position.x++; r.position.y++; r.size.x -= 2; r.size.y -= 2; } if (draw_center) vs->canvas_item_add_rect(p_canvas_item, Rect2(r.position, r.size), bg_color); Rect2i r_add = p_rect; vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x - additional_border_size[MARGIN_LEFT], r_add.position.y - additional_border_size[MARGIN_TOP]), Size2(r_add.size.width + additional_border_size[MARGIN_LEFT] + additional_border_size[MARGIN_RIGHT], additional_border_size[MARGIN_TOP])), light_color); vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x - additional_border_size[MARGIN_LEFT], r_add.position.y), Size2(additional_border_size[MARGIN_LEFT], r_add.size.height)), light_color); vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x + r_add.size.width, r_add.position.y), Size2(additional_border_size[MARGIN_RIGHT], r_add.size.height)), dark_color); vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x - additional_border_size[MARGIN_LEFT], r_add.position.y + r_add.size.height), Size2(r_add.size.width + additional_border_size[MARGIN_LEFT] + additional_border_size[MARGIN_RIGHT], additional_border_size[MARGIN_BOTTOM])), dark_color); }
void StyleBoxFlat::draw(RID p_canvas_item,const Rect2& p_rect) const { VisualServer *vs = VisualServer::get_singleton(); Rect2i r = p_rect; for (int i=0;i<border_size;i++) { Color color_upleft=light_color; Color color_downright=dark_color; if (blend) { color_upleft.r=(border_size-i)*color_upleft.r/border_size + i*bg_color.r/border_size; color_upleft.g=(border_size-i)*color_upleft.g/border_size + i*bg_color.g/border_size; color_upleft.b=(border_size-i)*color_upleft.b/border_size + i*bg_color.b/border_size; color_downright.r=(border_size-i)*color_downright.r/border_size + i*bg_color.r/border_size; color_downright.g=(border_size-i)*color_downright.g/border_size + i*bg_color.g/border_size; color_downright.b=(border_size-i)*color_downright.b/border_size + i*bg_color.b/border_size; } vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i( r.pos.x,r.pos.y+r.size.y-1), Size2(r.size.x ,1 )),color_downright); vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i( r.pos.x+r.size.x-1,r.pos.y ), Size2( 1 ,r.size.y )), color_downright); vs->canvas_item_add_rect(p_canvas_item, Rect2( r.pos, Size2(r.size.x ,1 )), color_upleft); vs->canvas_item_add_rect(p_canvas_item, Rect2( r.pos, Size2( 1 ,r.size.y )), color_upleft); r.pos.x++; r.pos.y++; r.size.x-=2; r.size.y-=2; } if (draw_center) vs->canvas_item_add_rect(p_canvas_item, Rect2( r.pos, r.size) , bg_color ); }
RID _add_body(Physics2DServer::ShapeType p_shape, const Matrix32& p_xform) { VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); RID body = ps->body_create(); ps->body_add_shape(body,body_shape_data[p_shape].shape); ps->body_set_space(body,space); ps->body_set_continuous_collision_detection_mode(body,Physics2DServer::CCD_MODE_CAST_SHAPE); ps->body_set_state(body,Physics2DServer::BODY_STATE_TRANSFORM,p_xform); // print_line("add body with xform: "+p_xform); RID sprite = vs->canvas_item_create(); vs->canvas_item_set_parent(sprite,canvas); vs->canvas_item_set_transform(sprite,p_xform); Size2 imgsize( vs->texture_get_width(body_shape_data[p_shape].image),vs->texture_get_height(body_shape_data[p_shape].image) ); vs->canvas_item_add_texture_rect(sprite,Rect2(-imgsize/2.0,imgsize),body_shape_data[p_shape].image); ps->body_set_force_integration_callback(body,this,"_body_moved",sprite); // RID q = ps->query_create(this,"_body_moved",sprite); // ps->query_body_state(q,body); return body; }
void _create_body_shape_data() { VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); // SEGMENT { DVector<uint8_t> pixels; pixels.resize(32*2*2); for(int i=0;i<2;i++) { for(int j=0;j<32;j++) { pixels.set(i*32*2+j*2+0,(j==0)?255:0); pixels.set(i*32*2+j*2+1,255); } } Image image(32,2,0,Image::FORMAT_LA8,pixels); body_shape_data[Physics2DServer::SHAPE_SEGMENT].image=vs->texture_create_from_image(image); RID segment_shape = ps->shape_create(Physics2DServer::SHAPE_SEGMENT); Rect2 sg(Point2(-16,0),Point2(16,0)); ps->shape_set_data(segment_shape,sg); body_shape_data[Physics2DServer::SHAPE_SEGMENT].shape = segment_shape; } // CIRCLE { DVector<uint8_t> pixels; pixels.resize(32*32*2); for(int i=0;i<32;i++) { for(int j=0;j<32;j++) { bool black=Vector2(i-16,j-16).length_squared() < 16*16; pixels.set(i*32*2+j*2+0,(i==16 || j==16)?255:0); pixels.set(i*32*2+j*2+1,black?255:0); } } Image image(32,32,0,Image::FORMAT_LA8,pixels); body_shape_data[Physics2DServer::SHAPE_CIRCLE].image=vs->texture_create_from_image(image); RID circle_shape = ps->shape_create(Physics2DServer::SHAPE_CIRCLE); ps->shape_set_data(circle_shape,16); body_shape_data[Physics2DServer::SHAPE_CIRCLE].shape = circle_shape; } // BOX { DVector<uint8_t> pixels; pixels.resize(32*32*2); for(int i=0;i<32;i++) { for(int j=0;j<32;j++) { bool black=i>0 && i<31 && j>0 && j<31; pixels.set(i*32*2+j*2+0,black?0:255); pixels.set(i*32*2+j*2+1,255); } } Image image(32,32,0,Image::FORMAT_LA8,pixels); body_shape_data[Physics2DServer::SHAPE_RECTANGLE].image=vs->texture_create_from_image(image); RID rectangle_shape = ps->shape_create(Physics2DServer::SHAPE_RECTANGLE); ps->shape_set_data(rectangle_shape,Vector2(16,16)); body_shape_data[Physics2DServer::SHAPE_RECTANGLE].shape = rectangle_shape; } // CAPSULE { DVector<uint8_t> pixels; pixels.resize(32*64*2); for(int i=0;i<64;i++) { for(int j=0;j<32;j++) { int si = i>48 ? i - 32 : (i<16 ? i : 16); bool black=Vector2(si-16,j-16).length_squared() < 16*16; pixels.set(i*32*2+j*2+0,(i==16 || j==16 || i==48)?255:0); pixels.set(i*32*2+j*2+1,black?255:0); } } Image image(32,64,0,Image::FORMAT_LA8,pixels); body_shape_data[Physics2DServer::SHAPE_CAPSULE].image=vs->texture_create_from_image(image); RID capsule_shape = ps->shape_create(Physics2DServer::SHAPE_CAPSULE); ps->shape_set_data(capsule_shape,Vector2(16,32)); body_shape_data[Physics2DServer::SHAPE_CAPSULE].shape = capsule_shape; } // CONVEX { Image image(convex_png); body_shape_data[Physics2DServer::SHAPE_CUSTOM+1].image=vs->texture_create_from_image(image); RID convex_polygon_shape = ps->shape_create(Physics2DServer::SHAPE_CONVEX_POLYGON); DVector<Vector2> arr; Point2 sb(32,32); arr.push_back(Point2(20,3)-sb); arr.push_back(Point2(58,23)-sb); arr.push_back(Point2(55,54)-sb); arr.push_back(Point2(27,60)-sb); arr.push_back(Point2(5,56)-sb); arr.push_back(Point2(4,20)-sb); arr.push_back(Point2(11,7)-sb); ps->shape_set_data(convex_polygon_shape,arr); body_shape_data[Physics2DServer::SHAPE_CUSTOM+1].shape = convex_polygon_shape; } }
virtual void init() { VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); space=ps->space_create(); ps->space_set_active(space,true); ps->set_active(true); ps->area_set_param(space,Physics2DServer::AREA_PARAM_GRAVITY_VECTOR,Vector2(0,1)); ps->area_set_param(space,Physics2DServer::AREA_PARAM_GRAVITY,98); { RID vp = vs->viewport_create(); canvas = vs->canvas_create(); vs->viewport_attach_canvas(vp,canvas); vs->viewport_attach_to_screen(vp,Rect2(Vector2(),OS::get_singleton()->get_window_size())); Matrix32 smaller; //smaller.scale(Vector2(0.6,0.6)); //smaller.elements[2]=Vector2(100,0); //view_xform = smaller; vs->viewport_set_canvas_transform(vp,canvas,view_xform); } ray = vs->canvas_item_create(); vs->canvas_item_set_parent(ray,canvas); //ray_query = ps->query_create(this,"_ray_query_callback",Variant()); //ps->query_intersection(ray_query,space); _create_body_shape_data(); for(int i=0;i<32;i++) { Physics2DServer::ShapeType types[4]={ Physics2DServer::SHAPE_CIRCLE, Physics2DServer::SHAPE_CAPSULE, Physics2DServer::SHAPE_RECTANGLE, Physics2DServer::SHAPE_CONVEX_POLYGON, }; Physics2DServer::ShapeType type = types[i%4]; // type=Physics2DServer::SHAPE_SEGMENT; _add_body(type,Matrix32(i*0.8,Point2(152+i*40,100-40*i))); //if (i==0) // ps->body_set_mode(b,Physics2DServer::BODY_MODE_STATIC); } //RID b= _add_body(Physics2DServer::SHAPE_CIRCLE,Matrix32(0,Point2(101,140))); //ps->body_set_mode(b,Physics2DServer::BODY_MODE_STATIC); Point2 prev; Vector<Point2> parr; for(int i=0;i<30;i++) { Point2 p(i*60,Math::randf() * 70+340); if (i>0) { parr.push_back(prev); parr.push_back(p); } prev=p; } _add_concave(parr); //_add_plane(Vector2(0.0,-1).normalized(),-300); //_add_plane(Vector2(1,0).normalized(),50); //_add_plane(Vector2(-1,0).normalized(),-600); }
void ScrollBar::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { RID ci = get_canvas_item(); Ref<Texture> decr = highlight == HIGHLIGHT_DECR ? get_icon("decrement_highlight") : get_icon("decrement"); Ref<Texture> incr = highlight == HIGHLIGHT_INCR ? get_icon("increment_highlight") : get_icon("increment"); Ref<StyleBox> bg = has_focus() ? get_stylebox("scroll_focus") : get_stylebox("scroll"); Ref<StyleBox> grabber; if (drag.active) grabber = get_stylebox("grabber_pressed"); else if (highlight == HIGHLIGHT_RANGE) grabber = get_stylebox("grabber_highlight"); else grabber = get_stylebox("grabber"); Point2 ofs; VisualServer *vs = VisualServer::get_singleton(); vs->canvas_item_add_texture_rect(ci, Rect2(Point2(), decr->get_size()), decr->get_rid()); if (orientation == HORIZONTAL) ofs.x += decr->get_width(); else ofs.y += decr->get_height(); Size2 area = get_size(); if (orientation == HORIZONTAL) area.width -= incr->get_width() + decr->get_width(); else area.height -= incr->get_height() + decr->get_height(); bg->draw(ci, Rect2(ofs, area)); if (orientation == HORIZONTAL) ofs.width += area.width; else ofs.height += area.height; vs->canvas_item_add_texture_rect(ci, Rect2(ofs, decr->get_size()), incr->get_rid()); Rect2 grabber_rect; if (orientation == HORIZONTAL) { grabber_rect.size.width = get_grabber_size(); grabber_rect.size.height = get_size().height; grabber_rect.position.y = 0; grabber_rect.position.x = get_grabber_offset() + decr->get_width() + bg->get_margin(MARGIN_LEFT); } else { grabber_rect.size.width = get_size().width; grabber_rect.size.height = get_grabber_size(); grabber_rect.position.y = get_grabber_offset() + decr->get_height() + bg->get_margin(MARGIN_TOP); grabber_rect.position.x = 0; } grabber->draw(ci, grabber_rect); } if (p_what == NOTIFICATION_ENTER_TREE) { if (has_node(drag_slave_path)) { Node *n = get_node(drag_slave_path); drag_slave = n->cast_to<Control>(); } if (drag_slave) { drag_slave->connect("gui_input", this, "_drag_slave_input"); drag_slave->connect("tree_exited", this, "_drag_slave_exit", varray(), CONNECT_ONESHOT); } } if (p_what == NOTIFICATION_EXIT_TREE) { if (drag_slave) { drag_slave->disconnect("gui_input", this, "_drag_slave_input"); drag_slave->disconnect("tree_exited", this, "_drag_slave_exit"); } drag_slave = NULL; } if (p_what == NOTIFICATION_FIXED_PROCESS) { if (scrolling) { if (get_value() != target_scroll) { double target = target_scroll - get_value(); double dist = sqrt(target * target); double vel = ((target / dist) * 500) * get_fixed_process_delta_time(); if (vel >= dist) { set_value(target_scroll); } else { set_value(get_value() + vel); } } else { scrolling = false; set_fixed_process(false); } } else if (drag_slave_touching) { if (drag_slave_touching_deaccel) { Vector2 pos = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0); pos += drag_slave_speed * get_fixed_process_delta_time(); bool turnoff = false; if (orientation == HORIZONTAL) { if (pos.x < 0) { pos.x = 0; turnoff = true; } if (pos.x > (get_max() - get_page())) { pos.x = get_max() - get_page(); turnoff = true; } set_value(pos.x); float sgn_x = drag_slave_speed.x < 0 ? -1 : 1; float val_x = Math::abs(drag_slave_speed.x); val_x -= 1000 * get_fixed_process_delta_time(); if (val_x < 0) { turnoff = true; } drag_slave_speed.x = sgn_x * val_x; } else { if (pos.y < 0) { pos.y = 0; turnoff = true; } if (pos.y > (get_max() - get_page())) { pos.y = get_max() - get_page(); turnoff = true; } set_value(pos.y); float sgn_y = drag_slave_speed.y < 0 ? -1 : 1; float val_y = Math::abs(drag_slave_speed.y); val_y -= 1000 * get_fixed_process_delta_time(); if (val_y < 0) { turnoff = true; } drag_slave_speed.y = sgn_y * val_y; } if (turnoff) { set_fixed_process(false); drag_slave_touching = false; drag_slave_touching_deaccel = false; } } else { if (time_since_motion == 0 || time_since_motion > 0.1) { Vector2 diff = drag_slave_accum - last_drag_slave_accum; last_drag_slave_accum = drag_slave_accum; drag_slave_speed = diff / get_fixed_process_delta_time(); } time_since_motion += get_fixed_process_delta_time(); } } } if (p_what == NOTIFICATION_MOUSE_EXIT) { highlight = HIGHLIGHT_NONE; update(); } }
void TileMap::_update_dirty_quadrants() { if (!pending_update) return; if (!is_inside_scene()) return; if (!tile_set.is_valid()) return; VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); while (dirty_quadrant_list.first()) { Quadrant &q = *dirty_quadrant_list.first()->self(); vs->canvas_item_clear(q.canvas_item); ps->body_clear_shapes(q.static_body); for(int i=0;i<q.cells.size();i++) { Map<PosKey,Cell>::Element *E=tile_map.find( q.cells[i] ); Cell &c=E->get(); //moment of truth if (!tile_set->has_tile(c.id)) continue; Ref<Texture> tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); Vector2 offset = Point2( E->key().x, E->key().y )*cell_size - q.pos; if (!tex.is_valid()) continue; Rect2 r = tile_set->tile_get_region(c.id); Size2 s = tex->get_size(); if (r==Rect2()) s = tex->get_size(); else { s = r.size; r.pos.x+=fp_adjust; r.pos.y+=fp_adjust; r.size.x-=fp_adjust*2.0; r.size.y-=fp_adjust*2.0; } Rect2 rect; rect.pos=offset.floor(); rect.size=s; rect.size.x+=fp_adjust; rect.size.y+=fp_adjust; if (c.flip_h) rect.size.x=-rect.size.x; if (c.flip_v) rect.size.y=-rect.size.y; rect.pos+=tile_ofs; if (r==Rect2()) { tex->draw_rect(q.canvas_item,rect); } else { tex->draw_rect_region(q.canvas_item,rect,r); } Vector< Ref<Shape2D> > shapes = tile_set->tile_get_shapes(c.id); for(int i=0;i<shapes.size();i++) { Ref<Shape2D> shape = shapes[i]; if (shape.is_valid()) { Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id); Matrix32 xform; xform.set_origin(offset.floor()+shape_ofs); if (c.flip_h) { xform.elements[0]=-xform.elements[0]; xform.elements[2].x+=s.x; } if (c.flip_v) { xform.elements[1]=-xform.elements[1]; xform.elements[2].y+=s.y; } ps->body_add_shape(q.static_body,shape->get_rid(),xform); } } } dirty_quadrant_list.remove( dirty_quadrant_list.first() ); } pending_update=false; _recompute_rect_cache(); }
void TileMap::_update_dirty_quadrants() { if (!pending_update) return; if (!is_inside_tree()) return; if (!tile_set.is_valid()) return; VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); Vector2 tofs = get_cell_draw_offset(); Vector2 tcenter = cell_size/2; Matrix32 nav_rel; if (navigation) nav_rel = get_relative_transform_to_parent(navigation); Vector2 qofs; SceneTree *st=SceneTree::get_singleton(); Color debug_collision_color; bool debug_shapes = st && st->is_debugging_collisions_hint(); if (debug_shapes) { debug_collision_color=st->get_debug_collisions_color(); } while (dirty_quadrant_list.first()) { Quadrant &q = *dirty_quadrant_list.first()->self(); for (List<RID>::Element *E=q.canvas_items.front();E;E=E->next()) { vs->free(E->get()); } q.canvas_items.clear(); ps->body_clear_shapes(q.body); int shape_idx=0; if (navigation) { for(Map<PosKey,Quadrant::NavPoly>::Element *E=q.navpoly_ids.front();E;E=E->next()) { navigation->navpoly_remove(E->get().id); } q.navpoly_ids.clear(); } for(Map<PosKey,Quadrant::Occluder>::Element *E=q.occluder_instances.front();E;E=E->next()) { VS::get_singleton()->free(E->get().id); } q.occluder_instances.clear(); Ref<CanvasItemMaterial> prev_material; RID prev_canvas_item; RID prev_debug_canvas_item; for(int i=0;i<q.cells.size();i++) { Map<PosKey,Cell>::Element *E=tile_map.find( q.cells[i] ); Cell &c=E->get(); //moment of truth if (!tile_set->has_tile(c.id)) continue; Ref<Texture> tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); Vector2 wofs = _map_to_world(E->key().x, E->key().y); Vector2 offset = wofs - q.pos + tofs; if (!tex.is_valid()) continue; Ref<CanvasItemMaterial> mat = tile_set->tile_get_material(c.id); RID canvas_item; RID debug_canvas_item; if (prev_canvas_item==RID() || prev_material!=mat) { canvas_item=vs->canvas_item_create(); if (mat.is_valid()) vs->canvas_item_set_material(canvas_item,mat->get_rid()); vs->canvas_item_set_parent( canvas_item, get_canvas_item() ); Matrix32 xform; xform.set_origin( q.pos ); vs->canvas_item_set_transform( canvas_item, xform ); vs->canvas_item_set_light_mask(canvas_item,get_light_mask()); vs->canvas_item_set_blend_mode(canvas_item,VS::MaterialBlendMode(get_blend_mode())); q.canvas_items.push_back(canvas_item); if (debug_shapes) { debug_canvas_item=vs->canvas_item_create(); vs->canvas_item_set_parent( debug_canvas_item, canvas_item ); vs->canvas_item_set_z_as_relative_to_parent(debug_canvas_item,false); vs->canvas_item_set_z(debug_canvas_item,VS::CANVAS_ITEM_Z_MAX-1); q.canvas_items.push_back(debug_canvas_item); prev_debug_canvas_item=debug_canvas_item; } prev_canvas_item=canvas_item; prev_material=mat; } else { canvas_item=prev_canvas_item; if (debug_shapes) { debug_canvas_item=prev_debug_canvas_item; } } Rect2 r = tile_set->tile_get_region(c.id); Size2 s = tex->get_size(); if (r==Rect2()) s = tex->get_size(); else { s = r.size; r.pos.x+=fp_adjust; r.pos.y+=fp_adjust; r.size.x-=fp_adjust*2.0; r.size.y-=fp_adjust*2.0; } Rect2 rect; rect.pos=offset.floor(); rect.size=s; if (rect.size.y > rect.size.x) { if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) tile_ofs.y += rect.size.y - rect.size.x; } else if (rect.size.y < rect.size.x) { if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) tile_ofs.x += rect.size.x - rect.size.y; } /* rect.size.x+=fp_adjust; rect.size.y+=fp_adjust;*/ if (c.transpose) SWAP(tile_ofs.x, tile_ofs.y); if (c.flip_h) { rect.size.x=-rect.size.x; tile_ofs.x=-tile_ofs.x; } if (c.flip_v) { rect.size.y=-rect.size.y; tile_ofs.y=-tile_ofs.y; } Vector2 center_ofs; if (tile_origin==TILE_ORIGIN_TOP_LEFT) { rect.pos+=tile_ofs; } else if (tile_origin==TILE_ORIGIN_BOTTOM_LEFT) { rect.pos+=tile_ofs; if(c.transpose) { if(c.flip_h) rect.pos.x-=cell_size.x; else rect.pos.x+=cell_size.x; } else { if(c.flip_v) rect.pos.y-=cell_size.y; else rect.pos.y+=cell_size.y; } } else if (tile_origin==TILE_ORIGIN_CENTER) { rect.pos+=tcenter; Vector2 center = (s/2) - tile_ofs; center_ofs=tcenter-(s/2); if (c.flip_h) rect.pos.x-=s.x-center.x; else rect.pos.x-=center.x; if (c.flip_v) rect.pos.y-=s.y-center.y; else rect.pos.y-=center.y; } if (r==Rect2()) { tex->draw_rect(canvas_item,rect,false,Color(1,1,1),c.transpose); } else { tex->draw_rect_region(canvas_item,rect,r,Color(1,1,1),c.transpose); } Vector< Ref<Shape2D> > shapes = tile_set->tile_get_shapes(c.id); for(int i=0;i<shapes.size();i++) { Ref<Shape2D> shape = shapes[i]; if (shape.is_valid()) { Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id); Matrix32 xform; xform.set_origin(offset.floor()); _fix_cell_transform(xform,c,shape_ofs+center_ofs,s); if (debug_canvas_item) { vs->canvas_item_add_set_transform(debug_canvas_item,xform); shape->draw(debug_canvas_item,debug_collision_color); } ps->body_add_shape(q.body,shape->get_rid(),xform); ps->body_set_shape_metadata(q.body,shape_idx++,Vector2(E->key().x,E->key().y)); } } if (debug_canvas_item) { vs->canvas_item_add_set_transform(debug_canvas_item,Matrix32()); } if (navigation) { Ref<NavigationPolygon> navpoly = tile_set->tile_get_navigation_polygon(c.id); if (navpoly.is_valid()) { Vector2 npoly_ofs = tile_set->tile_get_navigation_polygon_offset(c.id); Matrix32 xform; xform.set_origin(offset.floor()+q.pos); _fix_cell_transform(xform,c,npoly_ofs+center_ofs,s); int pid = navigation->navpoly_create(navpoly,nav_rel * xform); Quadrant::NavPoly np; np.id=pid; np.xform=xform; q.navpoly_ids[E->key()]=np; } } Ref<OccluderPolygon2D> occluder=tile_set->tile_get_light_occluder(c.id); if (occluder.is_valid()) { Vector2 occluder_ofs = tile_set->tile_get_occluder_offset(c.id); Matrix32 xform; xform.set_origin(offset.floor()+q.pos); _fix_cell_transform(xform,c,occluder_ofs+center_ofs,s); RID orid = VS::get_singleton()->canvas_light_occluder_create(); VS::get_singleton()->canvas_light_occluder_set_transform(orid,get_global_transform() * xform); VS::get_singleton()->canvas_light_occluder_set_polygon(orid,occluder->get_rid()); VS::get_singleton()->canvas_light_occluder_attach_to_canvas(orid,get_canvas()); VS::get_singleton()->canvas_light_occluder_set_light_mask(orid,occluder_light_mask); Quadrant::Occluder oc; oc.xform=xform; oc.id=orid; q.occluder_instances[E->key()]=oc; } } dirty_quadrant_list.remove( dirty_quadrant_list.first() ); quadrant_order_dirty=true; } pending_update=false; if (quadrant_order_dirty) { for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) { Quadrant &q=E->get(); for (List<RID>::Element *E=q.canvas_items.front();E;E=E->next()) { VS::get_singleton()->canvas_item_raise(E->get()); } } quadrant_order_dirty=false; } for(int i=0;i<get_child_count();i++) { CanvasItem *c=get_child(i)->cast_to<CanvasItem>(); if (c) VS::get_singleton()->canvas_item_raise(c->get_canvas_item()); } _recompute_rect_cache(); }
void Skeleton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { if (dirty) { dirty = false; _make_dirty(); // property make it dirty } } break; case NOTIFICATION_EXIT_WORLD: { } break; case NOTIFICATION_TRANSFORM_CHANGED: { if (dirty) break; //will be eventually updated //if moved, just update transforms VisualServer *vs = VisualServer::get_singleton(); const Bone *bonesptr = bones.ptr(); int len = bones.size(); Transform global_transform = get_global_transform(); Transform global_transform_inverse = global_transform.affine_inverse(); for (int i = 0; i < len; i++) { const Bone &b = bonesptr[i]; vs->skeleton_bone_set_transform(skeleton, i, global_transform * (b.transform_final * global_transform_inverse)); } } break; case NOTIFICATION_UPDATE_SKELETON: { VisualServer *vs = VisualServer::get_singleton(); Bone *bonesptr = bones.ptrw(); int len = bones.size(); vs->skeleton_allocate(skeleton, len); // if same size, nothin really happens // pose changed, rebuild cache of inverses if (rest_global_inverse_dirty) { // calculate global rests and invert them for (int i = 0; i < len; i++) { Bone &b = bonesptr[i]; if (b.parent >= 0) b.rest_global_inverse = bonesptr[b.parent].rest_global_inverse * b.rest; else b.rest_global_inverse = b.rest; } for (int i = 0; i < len; i++) { Bone &b = bonesptr[i]; b.rest_global_inverse.affine_invert(); } rest_global_inverse_dirty = false; } Transform global_transform = get_global_transform(); Transform global_transform_inverse = global_transform.affine_inverse(); for (int i = 0; i < len; i++) { Bone &b = bonesptr[i]; if (b.disable_rest) { if (b.enabled) { Transform pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } if (b.parent >= 0) { b.pose_global = bonesptr[b.parent].pose_global * pose; } else { b.pose_global = pose; } } else { if (b.parent >= 0) { b.pose_global = bonesptr[b.parent].pose_global; } else { b.pose_global = Transform(); } } } else { if (b.enabled) { Transform pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } if (b.parent >= 0) { b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose); } else { b.pose_global = b.rest * pose; } } else { if (b.parent >= 0) { b.pose_global = bonesptr[b.parent].pose_global * b.rest; } else { b.pose_global = b.rest; } } } b.transform_final = b.pose_global * b.rest_global_inverse; vs->skeleton_bone_set_transform(skeleton, i, global_transform * (b.transform_final * global_transform_inverse)); for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) { Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE(!obj); Spatial *sp = Object::cast_to<Spatial>(obj); ERR_CONTINUE(!sp); sp->set_transform(b.pose_global); } } dirty = false; } break; } }