DVector<Vector3> _Geometry::segment_intersects_convex(const Vector3& p_from, const Vector3& p_to,const Vector<Plane>& p_planes) { DVector<Vector3> r; Vector3 res,norm; if (!Geometry::segment_intersects_convex(p_from,p_to,p_planes.ptr(),p_planes.size(),&res,&norm)) return r; r.resize(2); r.set(0,res); r.set(1,norm); return r; }
DVector<Vector3> _Geometry::segment_intersects_sphere( const Vector3& p_from, const Vector3& p_to, const Vector3& p_sphere_pos,real_t p_sphere_radius) { DVector<Vector3> r; Vector3 res,norm; if (!Geometry::segment_intersects_sphere(p_from,p_to,p_sphere_pos,p_sphere_radius,&res,&norm)) return r; r.resize(2); r.set(0,res); r.set(1,norm); return r; }
DVector<Vector3> _Geometry::segment_intersects_cylinder( const Vector3& p_from, const Vector3& p_to, float p_height,float p_radius) { DVector<Vector3> r; Vector3 res,norm; if (!Geometry::segment_intersects_cylinder(p_from,p_to,p_height,p_radius,&res,&norm)) return r; r.resize(2); r.set(0,res); r.set(1,norm); return r; }
Array ResourcePreloader::_get_resources() const { DVector<String> names; Array arr; arr.resize(resources.size()); names.resize(resources.size()); Set<String> sorted_names; for(Map<StringName,RES >::Element *E=resources.front();E;E=E->next()) { sorted_names.insert(E->key()); } int i=0; for(Set<String>::Element *E=sorted_names.front();E;E=E->next()) { names.set(i,E->get()); arr[i]=resources[E->get()]; i++; } Array res; res.push_back(names); res.push_back(arr); return res; }
Variant::Variant(const Vector<Color>& p_array) { type=NIL; DVector<Color> v; int len=p_array.size(); v.resize(len); for (int i=0;i<len;i++) v.set(i,p_array[i]); *this=v; }
DVector<Vector2> _Geometry::get_closest_points_between_segments_2d( const Vector2& p1,const Vector2& q1, const Vector2& p2,const Vector2& q2) { Vector2 r1, r2; Geometry::get_closest_points_between_segments(p1,q1,p2,q2,r1,r2); DVector<Vector2> r; r.resize(2); r.set(0,r1); r.set(1,r2); return r; }
DVector<String> ResourcePreloader::_get_resource_list() const { DVector<String> res; res.resize(resources.size()); int i=0; for(Map<StringName,RES >::Element *E=resources.front();E;E=E->next(),i++) { res.set(i,E->key()); } return res; }
Variant ConvexPolygonShape2DSW::get_data() const { DVector<Vector2> dvr; dvr.resize(point_count); for(int i=0;i<point_count;i++) { dvr.set(i,points[i].pos); } return dvr; }
DVector<String> AnimationTreePlayer::_get_node_list() { List<StringName> nl; get_node_list(&nl); DVector<String> ret; ret.resize(nl.size()); int idx=0; for(List<StringName>::Element *E=nl.front();E;E=E->next()) { ret.set(idx++,E->get()); } return ret; }
DVector<String> Translation::_get_message_list() const { DVector<String> msgs; msgs.resize(translation_map.size()); int idx=0; for (const Map<StringName, StringName>::Element *E=translation_map.front();E;E=E->next()) { msgs.set(idx,E->key()); idx+=1; } return msgs; }
DVector<Vector3> ConcavePolygonShapeSW::get_faces() const { DVector<Vector3> rfaces; rfaces.resize(faces.size()*3); for(int i=0;i<faces.size();i++) { Face f=faces.get(i); for(int j=0;j<3;j++) { rfaces.set(i*3+j, vertices.get( f.indices[j] ) ); } } return rfaces; }
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; } }
bool NavigationPolygonEditor::forward_input_event(const InputEvent& p_event) { if (!node) return false; if (node->get_navigation_polygon().is_null()) { if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { create_nav->set_text("No NavigationPolygon resource on this node.\nCreate and assign one?"); create_nav->popup_centered_minsize(); } return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1);; } switch(p_event.type) { case InputEvent::MOUSE_BUTTON: { const InputEventMouseButton &mb=p_event.mouse_button; Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); Vector2 gpoint = Point2(mb.x,mb.y); Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); cpoint=canvas_item_editor->snap_point(cpoint); cpoint = node->get_global_transform().affine_inverse().xform(cpoint); //first check if a point is to be added (segment split) real_t grab_treshold=EDITOR_DEF("poly_editor/point_grab_radius",8); switch(mode) { case MODE_CREATE: { if (mb.button_index==BUTTON_LEFT && mb.pressed) { if (!wip_active) { wip.clear(); wip.push_back( cpoint ); wip_active=true; edited_point_pos=cpoint; edited_outline=-1; canvas_item_editor->get_viewport_control()->update(); edited_point=1; return true; } else { if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { //wip closed _wip_close(); return true; } else { wip.push_back( cpoint ); edited_point=wip.size(); canvas_item_editor->get_viewport_control()->update(); return true; //add wip point } } } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { _wip_close(); } } break; case MODE_EDIT: { if (mb.button_index==BUTTON_LEFT) { if (mb.pressed) { if (mb.mod.control) { //search edges int closest_outline=-1; int closest_idx=-1; Vector2 closest_pos; real_t closest_dist=1e10; for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { DVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); int pc=points.size(); DVector<Vector2>::Read poly=points.read(); for(int i=0;i<pc;i++) { Vector2 points[2] ={ xform.xform(poly[i]), xform.xform(poly[(i+1)%pc]) }; Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) continue; //not valid to reuse point real_t d = cp.distance_to(gpoint); if (d<closest_dist && d<grab_treshold) { closest_dist=d; closest_outline=j; closest_pos=cp; closest_idx=i; } } } if (closest_idx>=0) { pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); DVector<Point2> poly = pre_move_edit; poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); edited_point=closest_idx+1; edited_outline=closest_outline; edited_point_pos=xform.affine_inverse().xform(closest_pos); node->get_navigation_polygon()->set_outline(closest_outline,poly); canvas_item_editor->get_viewport_control()->update(); return true; } } else { //look for points to move int closest_outline=-1; int closest_idx=-1; Vector2 closest_pos; real_t closest_dist=1e10; for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { DVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); int pc=points.size(); DVector<Vector2>::Read poly=points.read(); for(int i=0;i<pc;i++) { Vector2 cp =xform.xform(poly[i]); real_t d = cp.distance_to(gpoint); if (d<closest_dist && d<grab_treshold) { closest_dist=d; closest_pos=cp; closest_outline=j; closest_idx=i; } } } if (closest_idx>=0) { pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); edited_point=closest_idx; edited_outline=closest_outline; edited_point_pos=xform.affine_inverse().xform(closest_pos); canvas_item_editor->get_viewport_control()->update(); return true; } } } else { if (edited_point!=-1) { //apply DVector<Vector2> poly = node->get_navigation_polygon()->get_outline(edited_outline); ERR_FAIL_INDEX_V(edited_point,poly.size(),false); poly.set(edited_point,edited_point_pos); undo_redo->create_action(TTR("Edit Poly")); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,poly); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,pre_move_edit); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->commit_action(); edited_point=-1; return true; } } } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { int closest_outline=-1; int closest_idx=-1; Vector2 closest_pos; real_t closest_dist=1e10; for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { DVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); int pc=points.size(); DVector<Vector2>::Read poly=points.read(); for(int i=0;i<pc;i++) { Vector2 cp =xform.xform(poly[i]); real_t d = cp.distance_to(gpoint); if (d<closest_dist && d<grab_treshold) { closest_dist=d; closest_pos=cp; closest_outline=j; closest_idx=i; } } } if (closest_idx>=0) { DVector<Vector2> poly = node->get_navigation_polygon()->get_outline(closest_outline); if (poly.size()>3) { undo_redo->create_action(TTR("Edit Poly (Remove Point)")); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); poly.remove(closest_idx); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->commit_action(); } else { undo_redo->create_action(TTR("Remove Poly And Point")); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"add_outline_at_index",poly,closest_outline); poly.remove(closest_idx); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"remove_outline",closest_outline); undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); undo_redo->commit_action(); } return true; } } } break; } } break; case InputEvent::MOUSE_MOTION: { const InputEventMouseMotion &mm=p_event.mouse_motion; if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { Vector2 gpoint = Point2(mm.x,mm.y); Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); cpoint=canvas_item_editor->snap_point(cpoint); edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); canvas_item_editor->get_viewport_control()->update(); } } break; } return false; }
RID VisualServer::_make_test_cube() { DVector<Vector3> vertices; DVector<Vector3> normals; DVector<float> tangents; DVector<Vector3> uvs; int vtx_idx=0; #define ADD_VTX(m_idx);\ vertices.push_back( face_points[m_idx] );\ normals.push_back( normal_points[m_idx] );\ tangents.push_back( normal_points[m_idx][1] );\ tangents.push_back( normal_points[m_idx][2] );\ tangents.push_back( normal_points[m_idx][0] );\ tangents.push_back( 1.0 );\ uvs.push_back( Vector3(uv_points[m_idx*2+0],uv_points[m_idx*2+1],0) );\ vtx_idx++;\ for (int i=0;i<6;i++) { Vector3 face_points[4]; Vector3 normal_points[4]; float uv_points[8]={0,0,0,1,1,1,1,0}; for (int j=0;j<4;j++) { float v[3]; v[0]=1.0; v[1]=1-2*((j>>1)&1); v[2]=v[1]*(1-2*(j&1)); for (int k=0;k<3;k++) { if (i<3) face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1); else face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1); } normal_points[j]=Vector3(); normal_points[j][i%3]=(i>=3?-1:1); } //tri 1 ADD_VTX(0); ADD_VTX(1); ADD_VTX(2); //tri 2 ADD_VTX(2); ADD_VTX(3); ADD_VTX(0); } RID test_cube = mesh_create(); Array d; d.resize(VS::ARRAY_MAX); d[VisualServer::ARRAY_NORMAL]= normals ; d[VisualServer::ARRAY_TANGENT]= tangents ; d[VisualServer::ARRAY_TEX_UV]= uvs ; d[VisualServer::ARRAY_VERTEX]= vertices ; DVector<int> indices; indices.resize(vertices.size()); for(int i=0;i<vertices.size();i++) indices.set(i,i); d[VisualServer::ARRAY_INDEX]=indices; mesh_add_surface( test_cube, PRIMITIVE_TRIANGLES,d ); RID material = fixed_material_create(); //material_set_flag(material, MATERIAL_FLAG_BILLBOARD_TOGGLE,true); fixed_material_set_texture( material, FIXED_MATERIAL_PARAM_DIFFUSE, get_test_texture() ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_SPECULAR_EXP, 70 ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_EMISSION, Vector3(0.2,0.2,0.2) ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_DIFFUSE, Color(1, 1, 1) ); fixed_material_set_param( material, FIXED_MATERIAL_PARAM_SPECULAR, Color(1,1,1) ); mesh_surface_set_material(test_cube, 0, material ); return test_cube; }