void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertexes, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const Vector<Plane> &p_tangents) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES); ERR_FAIL_COND(p_vertexes.size() < 3); #define ADD_POINT(n) \ { \ if (p_colors.size() > n) \ add_color(p_colors[n]); \ if (p_uvs.size() > n) \ add_uv(p_uvs[n]); \ if (p_uv2s.size() > n) \ add_uv2(p_uv2s[n]); \ if (p_normals.size() > n) \ add_normal(p_normals[n]); \ if (p_tangents.size() > n) \ add_tangent(p_tangents[n]); \ add_vertex(p_vertexes[n]); \ } for (int i = 0; i < p_vertexes.size() - 2; i++) { ADD_POINT(0); ADD_POINT(i + 1); ADD_POINT(i + 2); } #undef ADD_POINT }
RID VisualServer::make_sphere_mesh(int p_lats,int p_lons,float p_radius) { DVector<Vector3> vertices; DVector<Vector3> normals; for(int i = 1; i <= p_lats; i++) { double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats); double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double lat1 = Math_PI * (-0.5 + (double) i / p_lats); double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for(int j = p_lons; j >= 1; j--) { double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double lng1 = 2 * Math_PI * (double) (j) / p_lons; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); Vector3 v[4]={ Vector3(x1 * zr0, z0, y1 *zr0), Vector3(x1 * zr1, z1, y1 *zr1), Vector3(x0 * zr1, z1, y0 *zr1), Vector3(x0 * zr0, z0, y0 *zr0) }; #define ADD_POINT(m_idx)\ normals.push_back(v[m_idx]); \ vertices.push_back(v[m_idx]*p_radius);\ ADD_POINT(0); ADD_POINT(1); ADD_POINT(2); ADD_POINT(2); ADD_POINT(3); ADD_POINT(0); } } RID mesh = mesh_create(); Array d; d.resize(VS::ARRAY_MAX); d[ARRAY_VERTEX]=vertices; d[ARRAY_NORMAL]=normals; mesh_add_surface(mesh,PRIMITIVE_TRIANGLES,d); return mesh; }
void ImmediateGeometry::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) { for(int i = 1; i <= p_lats; i++) { double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats); double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double lat1 = Math_PI * (-0.5 + (double) i / p_lats); double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for(int j = p_lons; j >= 1; j--) { double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double lng1 = 2 * Math_PI * (double) (j) / p_lons; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); Vector3 v[4]={ Vector3(x1 * zr0, z0, y1 *zr0), Vector3(x1 * zr1, z1, y1 *zr1), Vector3(x0 * zr1, z1, y0 *zr1), Vector3(x0 * zr0, z0, y0 *zr0) }; #define ADD_POINT(m_idx)\ if (p_add_uv) {\ set_uv(Vector2(Math::atan2(v[m_idx].x,v[m_idx].z)/Math_PI * 0.5+0.5,v[m_idx].y*0.5+0.5));\ set_tangent(Plane(Vector3(-v[m_idx].z,v[m_idx].y,v[m_idx].x),1)); \ }\ set_normal(v[m_idx]);\ add_vertex(v[m_idx]*p_radius); ADD_POINT(0); ADD_POINT(1); ADD_POINT(2); ADD_POINT(2); ADD_POINT(3); ADD_POINT(0); } } }
static void _make_sphere(int p_lats, int p_lons, float p_radius, Ref<SurfaceTool> p_tool) { p_tool->begin(Mesh::PRIMITIVE_TRIANGLES); for(int i = 1; i <= p_lats; i++) { double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats); double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double lat1 = Math_PI * (-0.5 + (double) i / p_lats); double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for(int j = p_lons; j >= 1; j--) { double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double lng1 = 2 * Math_PI * (double) (j) / p_lons; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); Vector3 v[4]={ Vector3(x1 * zr0, z0, y1 *zr0), Vector3(x1 * zr1, z1, y1 *zr1), Vector3(x0 * zr1, z1, y0 *zr1), Vector3(x0 * zr0, z0, y0 *zr0) }; #define ADD_POINT(m_idx) \ p_tool->add_normal(v[m_idx]);\ p_tool->add_vertex(v[m_idx]*p_radius); ADD_POINT(0); ADD_POINT(1); ADD_POINT(2); ADD_POINT(2); ADD_POINT(3); ADD_POINT(0); } } }
void ImmediateGeometry::add_sphere(int p_lats,int p_lons,float p_radius) { for(int i = 1; i <= p_lats; i++) { double lat0 = Math_PI * (-0.5 + (double) (i - 1) / p_lats); double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double lat1 = Math_PI * (-0.5 + (double) i / p_lats); double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for(int j = p_lons; j >= 1; j--) { double lng0 = 2 * Math_PI * (double) (j - 1) / p_lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double lng1 = 2 * Math_PI * (double) (j) / p_lons; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); Vector3 v[4]={ Vector3(x1 * zr0, z0, y1 *zr0), Vector3(x1 * zr1, z1, y1 *zr1), Vector3(x0 * zr1, z1, y0 *zr1), Vector3(x0 * zr0, z0, y0 *zr0) }; #define ADD_POINT(m_idx)\ set_normal(v[m_idx]);\ add_vertex(v[m_idx]*p_radius); ADD_POINT(0); ADD_POINT(1); ADD_POINT(2); ADD_POINT(2); ADD_POINT(3); ADD_POINT(0); } } }
EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { scenario = VS::get_singleton()->scenario_create(); viewport = VS::get_singleton()->viewport_create(); VS::get_singleton()->viewport_set_as_render_target(viewport,true); VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED); VS::get_singleton()->viewport_set_scenario(viewport,scenario); VS::ViewportRect vr; vr.x=0; vr.y=0; vr.width=128; vr.height=128; VS::get_singleton()->viewport_set_rect(viewport,vr); camera = VS::get_singleton()->camera_create(); VS::get_singleton()->viewport_attach_camera(viewport,camera); VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3))); VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); light_instance = VS::get_singleton()->instance_create2(light,scenario); VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7)); VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0)); light_instance2 = VS::get_singleton()->instance_create2(light2,scenario); VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); sphere = VS::get_singleton()->mesh_create(); sphere_instance = VS::get_singleton()->instance_create2(sphere,scenario); int lats=32; int lons=32; float radius=1.0; PoolVector<Vector3> vertices; PoolVector<Vector3> normals; PoolVector<Vector2> uvs; PoolVector<float> tangents; Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5); for(int i = 1; i <= lats; i++) { double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats); double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double lat1 = Math_PI * (-0.5 + (double) i / lats); double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for(int j = lons; j >= 1; j--) { double lng0 = 2 * Math_PI * (double) (j - 1) / lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double lng1 = 2 * Math_PI * (double) (j) / lons; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); Vector3 v[4]={ Vector3(x1 * zr0, z0, y1 *zr0), Vector3(x1 * zr1, z1, y1 *zr1), Vector3(x0 * zr1, z1, y0 *zr1), Vector3(x0 * zr0, z0, y0 *zr0) }; #define ADD_POINT(m_idx) \ normals.push_back(v[m_idx]); \ vertices.push_back(v[m_idx] * radius); \ { \ Vector2 uv(Math::atan2(v[m_idx].x, v[m_idx].z), Math::atan2(-v[m_idx].y, v[m_idx].z)); \ uv /= Math_PI; \ uv *= 4.0; \ uv = uv * 0.5 + Vector2(0.5, 0.5); \ uvs.push_back(uv); \ } \ { \ Vector3 t = tt.xform(v[m_idx]); \ tangents.push_back(t.x); \ tangents.push_back(t.y); \ tangents.push_back(t.z); \ tangents.push_back(1.0); \ } ADD_POINT(0); ADD_POINT(1); ADD_POINT(2); ADD_POINT(2); ADD_POINT(3); ADD_POINT(0); } } Array arr; arr.resize(VS::ARRAY_MAX); arr[VS::ARRAY_VERTEX]=vertices; arr[VS::ARRAY_NORMAL]=normals; arr[VS::ARRAY_TANGENT]=tangents; arr[VS::ARRAY_TEX_UV]=uvs; VS::get_singleton()->mesh_add_surface(sphere,VS::PRIMITIVE_TRIANGLES,arr); }
MaterialEditor::MaterialEditor() { viewport = memnew( Viewport ); Ref<World> world; world.instance(); viewport->set_world(world); //use own world add_child(viewport); viewport->set_disable_input(true); camera = memnew( Camera ); camera->set_transform(Transform(Matrix3(),Vector3(0,0,3))); camera->set_perspective(45,0.1,10); viewport->add_child(camera); light1 = memnew( DirectionalLight ); light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); viewport->add_child(light1); light2 = memnew( DirectionalLight ); light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7)); light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7)); viewport->add_child(light2); sphere_instance = memnew( MeshInstance ); viewport->add_child(sphere_instance); box_instance = memnew( MeshInstance ); viewport->add_child(box_instance); Transform box_xform; box_xform.basis.rotate(Vector3(1,0,0),Math::deg2rad(25)); box_xform.basis = box_xform.basis * Matrix3().rotated(Vector3(0,1,0),Math::deg2rad(25)); box_xform.basis.scale(Vector3(0.8,0.8,0.8)); box_instance->set_transform(box_xform); { sphere_mesh.instance(); int lats=32; int lons=32; float radius=1.0; PoolVector<Vector3> vertices; PoolVector<Vector3> normals; PoolVector<Vector2> uvs; PoolVector<float> tangents; Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5); for(int i = 1; i <= lats; i++) { double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats); double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double lat1 = Math_PI * (-0.5 + (double) i / lats); double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for(int j = lons; j >= 1; j--) { double lng0 = 2 * Math_PI * (double) (j - 1) / lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double lng1 = 2 * Math_PI * (double) (j) / lons; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); Vector3 v[4]={ Vector3(x1 * zr0, z0, y1 *zr0), Vector3(x1 * zr1, z1, y1 *zr1), Vector3(x0 * zr1, z1, y0 *zr1), Vector3(x0 * zr0, z0, y0 *zr0) }; #define ADD_POINT(m_idx) \ normals.push_back(v[m_idx]);\ vertices.push_back(v[m_idx]*radius);\ { Vector2 uv(Math::atan2(v[m_idx].x,v[m_idx].z),Math::atan2(-v[m_idx].y,v[m_idx].z));\ uv/=Math_PI;\ uv*=4.0;\ uv=uv*0.5+Vector2(0.5,0.5);\ uvs.push_back(uv);\ }\ { Vector3 t = tt.xform(v[m_idx]);\ tangents.push_back(t.x);\ tangents.push_back(t.y);\ tangents.push_back(t.z);\ tangents.push_back(1.0);\ } ADD_POINT(0); ADD_POINT(1); ADD_POINT(2); ADD_POINT(2); ADD_POINT(3); ADD_POINT(0); } } Array arr; arr.resize(VS::ARRAY_MAX); arr[VS::ARRAY_VERTEX]=vertices; arr[VS::ARRAY_NORMAL]=normals; arr[VS::ARRAY_TANGENT]=tangents; arr[VS::ARRAY_TEX_UV]=uvs; sphere_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr); sphere_instance->set_mesh(sphere_mesh); } { box_mesh.instance(); PoolVector<Vector3> vertices; PoolVector<Vector3> normals; PoolVector<float> tangents; PoolVector<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); } 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 ; PoolVector<int> indices; indices.resize(vertices.size()); for(int i=0;i<vertices.size();i++) indices.set(i,i); d[VisualServer::ARRAY_INDEX]=indices; box_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d); box_instance->set_mesh(box_mesh); box_instance->hide(); } set_custom_minimum_size(Size2(1,150)*EDSCALE); HBoxContainer *hb = memnew( HBoxContainer ); add_child(hb); hb->set_area_as_parent_rect(2); VBoxContainer *vb_shape = memnew( VBoxContainer ); hb->add_child(vb_shape); sphere_switch = memnew( TextureButton ); sphere_switch->set_toggle_mode(true); sphere_switch->set_pressed(true); vb_shape->add_child(sphere_switch); sphere_switch->connect("pressed",this,"_button_pressed",varray(sphere_switch)); box_switch = memnew( TextureButton ); box_switch->set_toggle_mode(true); box_switch->set_pressed(false); vb_shape->add_child(box_switch); box_switch->connect("pressed",this,"_button_pressed",varray(box_switch)); hb->add_spacer(); VBoxContainer *vb_light = memnew( VBoxContainer ); hb->add_child(vb_light); light_1_switch = memnew( TextureButton ); light_1_switch->set_toggle_mode(true); vb_light->add_child(light_1_switch); light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch)); light_2_switch = memnew( TextureButton ); light_2_switch->set_toggle_mode(true); vb_light->add_child(light_2_switch); light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch)); first_enter=true; }
static void create_border_with_arrow(GtkWidget* nw, WindowData* windata) { int width; int height; int y; int norm_point_x; int norm_point_y; GtkArrowType arrow_type; GdkScreen* screen; int arrow_side1_width = DEFAULT_ARROW_WIDTH / 2; int arrow_side2_width = DEFAULT_ARROW_WIDTH / 2; int arrow_offset = DEFAULT_ARROW_OFFSET; GdkPoint* shape_points = NULL; int i = 0; int monitor; GdkRectangle monitor_geometry; width = windata->width; height = windata->height; screen = gdk_window_get_screen(GDK_WINDOW(gtk_widget_get_window(nw))); monitor = gdk_screen_get_monitor_at_point(screen, windata->point_x, windata->point_y); gdk_screen_get_monitor_geometry(screen, monitor, &monitor_geometry); windata->num_border_points = 5; arrow_type = get_notification_arrow_type(windata->win); norm_point_x = windata->point_x - monitor_geometry.x; norm_point_y = windata->point_y - monitor_geometry.y; /* Handle the offset and such */ switch (arrow_type) { case GTK_ARROW_UP: case GTK_ARROW_DOWN: if (norm_point_x < arrow_side1_width) { arrow_side1_width = 0; arrow_offset = 0; } else if (norm_point_x > monitor_geometry.width - arrow_side2_width) { arrow_side2_width = 0; arrow_offset = width - arrow_side1_width; } else { if (norm_point_x - arrow_side2_width + width >= monitor_geometry.width) { arrow_offset = width - monitor_geometry.width + norm_point_x; } else { arrow_offset = MIN(norm_point_x - arrow_side1_width, DEFAULT_ARROW_OFFSET); } if (arrow_offset == 0 || arrow_offset == width - arrow_side1_width) { windata->num_border_points++; } else { windata->num_border_points += 2; } } /* * Why risk this for official builds? If it's somehow off the * screen, it won't horribly impact the user. Definitely less * than an assertion would... */ #if 0 g_assert(arrow_offset + arrow_side1_width >= 0); g_assert(arrow_offset + arrow_side1_width + arrow_side2_width <= width); #endif windata->border_points = g_new0(GdkPoint, windata->num_border_points); shape_points = g_new0(GdkPoint, windata->num_border_points); windata->drawn_arrow_begin_x = arrow_offset; windata->drawn_arrow_middle_x = arrow_offset + arrow_side1_width; windata->drawn_arrow_end_x = arrow_offset + arrow_side1_width + arrow_side2_width; if (arrow_type == GTK_ARROW_UP) { windata->drawn_arrow_begin_y = DEFAULT_ARROW_HEIGHT; windata->drawn_arrow_middle_y = 0; windata->drawn_arrow_end_y = DEFAULT_ARROW_HEIGHT; if (arrow_side1_width == 0) { ADD_POINT(0, 0, 0, 0); } else { ADD_POINT(0, DEFAULT_ARROW_HEIGHT, 0, 0); if (arrow_offset > 0) { ADD_POINT(arrow_offset - (arrow_side2_width > 0 ? 0 : 1), DEFAULT_ARROW_HEIGHT, 0, 0); } ADD_POINT(arrow_offset + arrow_side1_width - (arrow_side2_width > 0 ? 0 : 1), 0, 0, 0); } if (arrow_side2_width > 0) { ADD_POINT(windata->drawn_arrow_end_x, windata->drawn_arrow_end_y, 1, 0); ADD_POINT(width - 1, DEFAULT_ARROW_HEIGHT, 1, 0); } ADD_POINT(width - 1, height - 1, 1, 1); ADD_POINT(0, height - 1, 0, 1); y = windata->point_y; } else { windata->drawn_arrow_begin_y = height - DEFAULT_ARROW_HEIGHT; windata->drawn_arrow_middle_y = height; windata->drawn_arrow_end_y = height - DEFAULT_ARROW_HEIGHT; ADD_POINT(0, 0, 0, 0); ADD_POINT(width - 1, 0, 1, 0); if (arrow_side2_width == 0) { ADD_POINT(width - 1, height, (arrow_side1_width > 0 ? 0 : 1), 0); } else { ADD_POINT(width - 1, height - DEFAULT_ARROW_HEIGHT, 1, 1); if (arrow_offset < width - arrow_side1_width) { ADD_POINT(arrow_offset + arrow_side1_width + arrow_side2_width, height - DEFAULT_ARROW_HEIGHT, 0, 1); } ADD_POINT(arrow_offset + arrow_side1_width, height, 0, 1); } if (arrow_side1_width > 0) { ADD_POINT(windata->drawn_arrow_begin_x - (arrow_side2_width > 0 ? 0 : 1), windata->drawn_arrow_begin_y, 0, 0); ADD_POINT(0, height - DEFAULT_ARROW_HEIGHT, 0, 1); } y = windata->point_y - height; } #if 0 g_assert(i == windata->num_border_points); g_assert(windata->point_x - arrow_offset - arrow_side1_width >= 0); #endif gtk_window_move(GTK_WINDOW(windata->win), windata->point_x - arrow_offset - arrow_side1_width, y); break; case GTK_ARROW_LEFT: case GTK_ARROW_RIGHT: if (norm_point_y < arrow_side1_width) { arrow_side1_width = 0; arrow_offset = norm_point_y; } else if (norm_point_y > monitor_geometry.height - arrow_side2_width) { arrow_side2_width = 0; arrow_offset = norm_point_y - arrow_side1_width; } break; default: g_assert_not_reached(); } g_assert(shape_points != NULL); #if GTK_CHECK_VERSION(3, 0, 0) /* FIXME!!! */ #else windata->window_region = gdk_region_polygon(shape_points, windata->num_border_points, GDK_EVEN_ODD_RULE); #endif g_free(shape_points); }
API int ImageKit_Image_DrawBresenhamCircle( ImageKit_Image *self, DIMENSION midpoint_x, DIMENSION midpoint_y, DIMENSION radius, REAL *color ) { int32_t f, dx, dy, sx, sy, x, y, r; int32_t c; REAL *ptr; r = radius; sx = midpoint_x; sy = midpoint_y; f = 1 - r; dx = 1; dy = -2 * r; x = 0; y = r; ADD_POINT(sx, sy + r); ADD_POINT(sx, sy - r); ADD_POINT(sx + r, sy); ADD_POINT(sx - r, sy); while (x < y) { if (f >= 0) { y -= 1; dy += 2; f += dy; } x += 1; dx += 2; f += dx; ADD_POINT(sx + x, sy + y); ADD_POINT(sx - x, sy + y); ADD_POINT(sx + x, sy - y); ADD_POINT(sx - x, sy - y); ADD_POINT(sx + y, sy + x); ADD_POINT(sx - y, sy + x); ADD_POINT(sx + y, sy - x); ADD_POINT(sx - y, sy - x); } return 1; }
API int ImageKit_Image_DrawBresenhamLine( ImageKit_Image *self, DIMENSION _x0, DIMENSION _y0, DIMENSION _x1, DIMENSION _y1, REAL *color ) { int32_t dx, dy; int32_t sx, sy; int32_t x0, y0; int32_t x1, y1; int32_t err, e2; int32_t res1, res2; int32_t c; REAL *ptr; x0 = _x0; x1 = _x1; y0 = _y0; y1 = _y1; dx = abs(x1 - x0); dy = abs(y1 - y0); sx = (x0 < x1) ? 1 : -1; sy = (y0 < y1) ? 1 : -1; err = dx - dy; while (1) { ADD_POINT(x0, y0); if (x0 == x1 && y0 == y1) { break; } e2 = 2 * err; /* Optimized for minimal branching. Same as: if (e2 > -dy) { err = err - dy; x0 = x0 + sx; } if (e2 < dx) { err = err + dx; y0 = y0 + sy; } */ res1 = e2 > -dy; res2 = e2 < dx; err = (err - (dy * res1)) + (dx * res2); x0 = x0 + (sx * res1); y0 = y0 + (sy * res2); } return 1; }
API int ImageKit_Image_DrawBresenhamEllipse( ImageKit_Image *self, DIMENSION _x0, DIMENSION _y0, DIMENSION _x1, DIMENSION _y1, REAL *color ) { int32_t a, b, b1, x0, y0, x1, y1, c; int64_t dx, dy, err, e2; REAL *ptr; x0 = _x0; x1 = _x1; y0 = _y0; y1 = _y1; a = abs(x1 - x0); b = abs(y1 - y0); b1 = b & 1; dx = 4 * ( 1 - a) * b * b; dy = 4 * (b1 + 1) * a * a; err = dx + dy + b1 * a * a; if (x0 > x1) { x0 = x1; x1 += a; } if (y0 > y1) { y0 = y1; } y0 += (b + 1) / 2; y1 = y0 - b1; a *= 8 * a; b1 = 8 * b * b; do { ADD_POINT(x1, y0); ADD_POINT(x0, y0); ADD_POINT(x0, y1); ADD_POINT(x1, y1); e2 = 2 * err; if (e2 <= dy) { // y step y0++; y1--; err += dy += a; } if (e2 >= dx || 2 * err > dy) { // x step x0++; x1--; err += dx += b1; } } while (x0 <= x1); while (y0 - y1 < b) { ADD_POINT(x0 - 1, y0); ADD_POINT(x1 + 1, y0); ADD_POINT(x0 - 1, y1); ADD_POINT(x1 + 1, y1); y0++; y1--; } return 1; }
EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { scenario = VS::get_singleton()->scenario_create(); viewport = VS::get_singleton()->viewport_create(); VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_DISABLED); VS::get_singleton()->viewport_set_scenario(viewport, scenario); VS::get_singleton()->viewport_set_size(viewport, 128, 128); VS::get_singleton()->viewport_set_transparent_background(viewport, true); VS::get_singleton()->viewport_set_active(viewport, true); VS::get_singleton()->viewport_set_vflip(viewport, true); viewport_texture = VS::get_singleton()->viewport_get_texture(viewport); camera = VS::get_singleton()->camera_create(); VS::get_singleton()->viewport_attach_camera(viewport, camera); VS::get_singleton()->camera_set_transform(camera, Transform(Basis(), Vector3(0, 0, 3))); VS::get_singleton()->camera_set_perspective(camera, 45, 0.1, 10); light = VS::get_singleton()->directional_light_create(); light_instance = VS::get_singleton()->instance_create2(light, scenario); VS::get_singleton()->instance_set_transform(light_instance, Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); light2 = VS::get_singleton()->directional_light_create(); VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7)); //VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7)); light_instance2 = VS::get_singleton()->instance_create2(light2, scenario); VS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); sphere = VS::get_singleton()->mesh_create(); sphere_instance = VS::get_singleton()->instance_create2(sphere, scenario); int lats = 32; int lons = 32; float radius = 1.0; PoolVector<Vector3> vertices; PoolVector<Vector3> normals; PoolVector<Vector2> uvs; PoolVector<float> tangents; Basis tt = Basis(Vector3(0, 1, 0), Math_PI * 0.5); for (int i = 1; i <= lats; i++) { double lat0 = Math_PI * (-0.5 + (double)(i - 1) / lats); double z0 = Math::sin(lat0); double zr0 = Math::cos(lat0); double lat1 = Math_PI * (-0.5 + (double)i / lats); double z1 = Math::sin(lat1); double zr1 = Math::cos(lat1); for (int j = lons; j >= 1; j--) { double lng0 = 2 * Math_PI * (double)(j - 1) / lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); double lng1 = 2 * Math_PI * (double)(j) / lons; double x1 = Math::cos(lng1); double y1 = Math::sin(lng1); Vector3 v[4] = { Vector3(x1 * zr0, z0, y1 * zr0), Vector3(x1 * zr1, z1, y1 * zr1), Vector3(x0 * zr1, z1, y0 * zr1), Vector3(x0 * zr0, z0, y0 * zr0) }; #define ADD_POINT(m_idx) \ normals.push_back(v[m_idx]); \ vertices.push_back(v[m_idx] * radius); \ { \ Vector2 uv(Math::atan2(v[m_idx].x, v[m_idx].z), Math::atan2(-v[m_idx].y, v[m_idx].z)); \ uv /= Math_PI; \ uv *= 4.0; \ uv = uv * 0.5 + Vector2(0.5, 0.5); \ uvs.push_back(uv); \ } \ { \ Vector3 t = tt.xform(v[m_idx]); \ tangents.push_back(t.x); \ tangents.push_back(t.y); \ tangents.push_back(t.z); \ tangents.push_back(1.0); \ } ADD_POINT(0); ADD_POINT(1); ADD_POINT(2); ADD_POINT(2); ADD_POINT(3); ADD_POINT(0); } } Array arr; arr.resize(VS::ARRAY_MAX); arr[VS::ARRAY_VERTEX] = vertices; arr[VS::ARRAY_NORMAL] = normals; arr[VS::ARRAY_TANGENT] = tangents; arr[VS::ARRAY_TEX_UV] = uvs; VS::get_singleton()->mesh_add_surface_from_arrays(sphere, VS::PRIMITIVE_TRIANGLES, arr); }