PoolVector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) { PoolVector<Plane> planes; Vector3 axis; axis[p_axis] = 1.0; Vector3 axis_neg; axis_neg[(p_axis + 1) % 3] = 1.0; axis_neg[(p_axis + 2) % 3] = 1.0; axis_neg[p_axis] = -1.0; for (int i = 0; i < p_sides; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides); normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides); planes.push_back(Plane(normal, p_radius)); for (int j = 1; j <= p_lats; j++) { Vector3 angle = normal.linear_interpolate(axis, j / (real_t)p_lats).normalized(); Vector3 pos = axis * p_height * 0.5 + angle * p_radius; planes.push_back(Plane(pos, angle)); planes.push_back(Plane(pos * axis_neg, angle * axis_neg)); } } return planes; }
void GridMapEditor::_update_areas_display() { if (!node) { return; } _clear_areas(); List<int> areas; node->get_area_list(&areas); Transform global_xf = node->get_global_transform(); for(List<int>::Element *E=areas.front();E;E=E->next()) { int area = E->get(); Color color; if (node->area_is_exterior_portal(area)) color=Color(1,1,1,0.2); else color.set_hsv(Math::fmod(area*0.37,1),Math::fmod(area*0.75,1),1.0,0.2); RID material = VisualServer::get_singleton()->fixed_material_create(); VisualServer::get_singleton()->fixed_material_set_param( material, VS::FIXED_MATERIAL_PARAM_DIFFUSE,color ); VisualServer::get_singleton()->fixed_material_set_param( material, VS::FIXED_MATERIAL_PARAM_EMISSION,0.5 ); VisualServer::get_singleton()->fixed_material_set_flag( material, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA, true ); RID mesh = VisualServer::get_singleton()->mesh_create(); PoolVector<Plane> planes; for(int i=0;i<3;i++) { Vector3 axis; axis[i]=1.0; planes.push_back(Plane(axis,1)); planes.push_back(Plane(-axis,0)); } VisualServer::get_singleton()->mesh_add_surface_from_planes(mesh,planes); VisualServer::get_singleton()->mesh_surface_set_material(mesh,0,material,true); AreaDisplay ad; ad.mesh=mesh; ad.instance = VisualServer::get_singleton()->instance_create2(mesh,node->get_world()->get_scenario()); Transform xform; Rect3 aabb = node->area_get_bounds(area); xform.origin=aabb.pos * node->get_cell_size(); xform.basis.scale(aabb.size * node->get_cell_size()); VisualServer::get_singleton()->instance_set_transform(ad.instance,global_xf * xform); this->areas.push_back(ad); } }
PoolVector<int> BitmapFont::_get_kernings() const { PoolVector<int> kernings; for (Map<KerningPairKey, int>::Element *E = kerning_map.front(); E; E = E->next()) { kernings.push_back(E->key().A); kernings.push_back(E->key().B); kernings.push_back(E->get()); } return kernings; }
void PlaneMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, z; Size2 start_pos = size * -0.5; PoolVector<Vector3> points; PoolVector<Vector3> normals; PoolVector<float> tangents; PoolVector<Vector2> uvs; PoolVector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ tangents.push_back(m_x); \ tangents.push_back(m_y); \ tangents.push_back(m_z); \ tangents.push_back(m_d); /* top + bottom */ z = start_pos.y; thisrow = point; prevrow = 0; for (j = 0; j <= (subdivide_d + 1); j++) { x = start_pos.x; for (i = 0; i <= (subdivide_w + 1); i++) { float u = i; float v = j; u /= (subdivide_w + 1.0); v /= (subdivide_d + 1.0); points.push_back(Vector3(-x, 0.0, -z)); normals.push_back(Vector3(0.0, 1.0, 0.0)); ADD_TANGENT(1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(u, v)); point++; if (i > 0 && j > 0) { indices.push_back(prevrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i); indices.push_back(thisrow + i - 1); }; x += size.x / (subdivide_w + 1.0); }; z += size.y / (subdivide_d + 1.0); prevrow = thisrow; thisrow = point; }; p_arr[VS::ARRAY_VERTEX] = points; p_arr[VS::ARRAY_NORMAL] = normals; p_arr[VS::ARRAY_TANGENT] = tangents; p_arr[VS::ARRAY_TEX_UV] = uvs; p_arr[VS::ARRAY_INDEX] = indices; }
PoolVector<Face3> Portal::get_faces(uint32_t p_usage_flags) const { if (!(p_usage_flags & FACES_ENCLOSING)) return PoolVector<Face3>(); Vector<Point2> shape = get_shape(); if (shape.size() == 0) return PoolVector<Face3>(); Vector2 center; for (int i = 0; i < shape.size(); i++) { center += shape[i]; } PoolVector<Face3> ret; center /= shape.size(); for (int i = 0; i < shape.size(); i++) { int n = (i + 1) % shape.size(); Face3 f; f.vertex[0] = Vector3(center.x, center.y, 0); f.vertex[1] = Vector3(shape[i].x, shape[i].y, 0); f.vertex[2] = Vector3(shape[n].x, shape[n].y, 0); ret.push_back(f); } return ret; }
PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { ERR_FAIL_COND_V(!points.has(p_from_id),PoolVector<Vector3>()); ERR_FAIL_COND_V(!points.has(p_to_id),PoolVector<Vector3>()); pass++; Point* a = points[p_from_id]; Point* b = points[p_to_id]; if (a==b) { PoolVector<Vector3> ret; ret.push_back(a->pos); return ret; } Point *begin_point=a; Point *end_point=b; bool found_route=_solve(begin_point,end_point); if (!found_route) return PoolVector<Vector3>(); //midpoints Point *p=end_point; int pc=1; //begin point while(p!=begin_point) { pc++; p=p->prev_point; } PoolVector<Vector3> path; path.resize(pc); { PoolVector<Vector3>::Write w = path.write(); Point *p=end_point; int idx=pc-1; while(p!=begin_point) { w[idx--]=p->pos; p=p->prev_point; } w[0]=p->pos; //assign first } return path; }
PoolVector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) { PoolVector<Plane> planes; for (int i = 0; i < p_sides; i++) { Vector3 normal; normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides); normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides); planes.push_back(Plane(normal, p_radius)); } Vector3 axis; axis[p_axis] = 1.0; planes.push_back(Plane(axis, p_height * 0.5)); planes.push_back(Plane(-axis, p_height * 0.5)); return planes; }
PoolVector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) { PoolVector<Plane> planes; planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x)); planes.push_back(Plane(Vector3(-1, 0, 0), p_extents.x)); planes.push_back(Plane(Vector3(0, 1, 0), p_extents.y)); planes.push_back(Plane(Vector3(0, -1, 0), p_extents.y)); planes.push_back(Plane(Vector3(0, 0, 1), p_extents.z)); planes.push_back(Plane(Vector3(0, 0, -1), p_extents.z)); return planes; }
PoolVector<int> BitmapFont::_get_chars() const { PoolVector<int> chars; const CharType *key = NULL; while ((key = char_map.next(key))) { const Character *c = char_map.getptr(*key); chars.push_back(*key); chars.push_back(c->texture_idx); chars.push_back(c->rect.position.x); chars.push_back(c->rect.position.y); chars.push_back(c->rect.size.x); chars.push_back(c->rect.size.y); chars.push_back(c->h_align); chars.push_back(c->v_align); chars.push_back(c->advance); } return chars; }
GridMapEditor::GridMapEditor(EditorNode *p_editor) { input_action=INPUT_NONE; editor=p_editor; undo_redo=p_editor->get_undo_redo(); int mw = EDITOR_DEF("editors/grid_map/palette_min_width",230); Control *ec = memnew( Control); ec->set_custom_minimum_size(Size2(mw,0)); add_child(ec); spatial_editor_hb = memnew( HBoxContainer ); SpatialEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb); options = memnew( MenuButton ); spatial_editor_hb->add_child(options); spatial_editor_hb->hide(); options->set_text("Grid"); options->get_popup()->add_check_item("Snap View",MENU_OPTION_LOCK_VIEW); options->get_popup()->add_separator(); options->get_popup()->add_item("Prev Level ("+keycode_get_string(KEY_MASK_CMD)+"Down Wheel)",MENU_OPTION_PREV_LEVEL); options->get_popup()->add_item("Next Level ("+keycode_get_string(KEY_MASK_CMD)+"Up Wheel)",MENU_OPTION_NEXT_LEVEL); options->get_popup()->add_separator(); options->get_popup()->add_check_item("Clip Disabled",MENU_OPTION_CLIP_DISABLED); options->get_popup()->set_item_checked( options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED), true ); options->get_popup()->add_check_item("Clip Above",MENU_OPTION_CLIP_ABOVE); options->get_popup()->add_check_item("Clip Below",MENU_OPTION_CLIP_BELOW); options->get_popup()->add_separator(); options->get_popup()->add_check_item("Edit X Axis",MENU_OPTION_X_AXIS,KEY_Z); options->get_popup()->add_check_item("Edit Y Axis",MENU_OPTION_Y_AXIS,KEY_X); options->get_popup()->add_check_item("Edit Z Axis",MENU_OPTION_Z_AXIS,KEY_C); options->get_popup()->set_item_checked( options->get_popup()->get_item_index(MENU_OPTION_Y_AXIS), true ); options->get_popup()->add_separator(); options->get_popup()->add_item("Cursor Rotate X",MENU_OPTION_CURSOR_ROTATE_X,KEY_A); options->get_popup()->add_item("Cursor Rotate Y",MENU_OPTION_CURSOR_ROTATE_Y,KEY_S); options->get_popup()->add_item("Cursor Rotate Z",MENU_OPTION_CURSOR_ROTATE_Z,KEY_D); options->get_popup()->add_item("Cursor Back Rotate X",MENU_OPTION_CURSOR_BACK_ROTATE_X,KEY_MASK_SHIFT+KEY_A); options->get_popup()->add_item("Cursor Back Rotate Y",MENU_OPTION_CURSOR_BACK_ROTATE_Y,KEY_MASK_SHIFT+KEY_S); options->get_popup()->add_item("Cursor Back Rotate Z",MENU_OPTION_CURSOR_BACK_ROTATE_Z,KEY_MASK_SHIFT+KEY_D); options->get_popup()->add_item("Cursor Clear Rotation",MENU_OPTION_CURSOR_CLEAR_ROTATION,KEY_W); options->get_popup()->add_separator(); options->get_popup()->add_check_item("Duplicate Selects",MENU_OPTION_DUPLICATE_SELECTS); options->get_popup()->add_separator(); options->get_popup()->add_item("Create Area",MENU_OPTION_SELECTION_MAKE_AREA,KEY_CONTROL+KEY_C); options->get_popup()->add_item("Create Exterior Connector",MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR); options->get_popup()->add_item("Erase Area",MENU_OPTION_REMOVE_AREA); options->get_popup()->add_separator(); options->get_popup()->add_item("Selection -> Duplicate",MENU_OPTION_SELECTION_DUPLICATE,KEY_MASK_SHIFT+KEY_INSERT); options->get_popup()->add_item("Selection -> Clear",MENU_OPTION_SELECTION_CLEAR,KEY_MASK_SHIFT+KEY_DELETE); //options->get_popup()->add_separator(); //options->get_popup()->add_item("Configure",MENU_OPTION_CONFIGURE); options->get_popup()->add_separator(); options->get_popup()->add_item("Settings", MENU_OPTION_GRIDMAP_SETTINGS); settings_dialog = memnew(ConfirmationDialog); settings_dialog->set_title("GridMap Settings"); add_child(settings_dialog); settings_vbc = memnew(VBoxContainer); settings_vbc->set_custom_minimum_size(Size2(200, 0)); settings_dialog->add_child(settings_vbc); settings_pick_distance = memnew(SpinBox); settings_pick_distance->set_max(10000.0f); settings_pick_distance->set_min(500.0f); settings_pick_distance->set_step(1.0f); settings_pick_distance->set_value(EDITOR_DEF("editors/grid_map/pick_distance", 5000.0)); settings_vbc->add_margin_child("Pick Distance:", settings_pick_distance); clip_mode=CLIP_DISABLED; options->get_popup()->connect("id_pressed", this,"_menu_option"); HBoxContainer *hb = memnew( HBoxContainer ); add_child(hb); hb->set_h_size_flags(SIZE_EXPAND_FILL); edit_mode = memnew(OptionButton); edit_mode->set_area_as_parent_rect(); edit_mode->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,24); edit_mode->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,14); edit_mode->add_item("Tiles"); edit_mode->add_item("Areas"); hb->add_child(edit_mode); edit_mode->set_h_size_flags(SIZE_EXPAND_FILL); mode_thumbnail = memnew( ToolButton ); mode_thumbnail->set_toggle_mode(true); mode_thumbnail->set_pressed(true); mode_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons")); hb->add_child(mode_thumbnail); mode_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL)); mode_list = memnew( ToolButton ); mode_list->set_toggle_mode(true); mode_list->set_pressed(false); mode_list->set_icon(p_editor->get_gui_base()->get_icon("FileList", "EditorIcons")); hb->add_child(mode_list); mode_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST)); EDITOR_DEF("editors/grid_map/preview_size",64) display_mode = DISPLAY_THUMBNAIL; selected_area=-1; theme_pallete = memnew( ItemList ); add_child(theme_pallete); theme_pallete->set_v_size_flags(SIZE_EXPAND_FILL); area_list = memnew( Tree ); add_child(area_list); area_list->set_v_size_flags(SIZE_EXPAND_FILL); area_list->hide(); spatial_editor_hb->add_child(memnew(VSeparator)); Label *fl = memnew(Label); fl->set_text(" Floor: "); spatial_editor_hb->add_child(fl); floor = memnew( SpinBox ); floor->set_min(-32767); floor->set_max(32767); floor->set_step(1); floor->get_line_edit()->add_constant_override("minimum_spaces",16); spatial_editor_hb->add_child(floor); floor->connect("value_changed",this,"_floor_changed"); edit_axis=Vector3::AXIS_Y; edit_floor[0]=-1; edit_floor[1]=-1; edit_floor[2]=-1; cursor_visible=false; selected_pallete=-1; lock_view=false; cursor_rot=0; last_mouseover=Vector3(-1,-1,-1); selection_mesh = VisualServer::get_singleton()->mesh_create(); duplicate_mesh = VisualServer::get_singleton()->mesh_create(); { //selection mesh create PoolVector<Vector3> lines; PoolVector<Vector3> triangles; for (int i=0;i<6;i++) { Vector3 face_points[4]; 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); } } triangles.push_back(face_points[0]*0.5+Vector3(0.5,0.5,0.5)); triangles.push_back(face_points[1]*0.5+Vector3(0.5,0.5,0.5)); triangles.push_back(face_points[2]*0.5+Vector3(0.5,0.5,0.5)); triangles.push_back(face_points[2]*0.5+Vector3(0.5,0.5,0.5)); triangles.push_back(face_points[3]*0.5+Vector3(0.5,0.5,0.5)); triangles.push_back(face_points[0]*0.5+Vector3(0.5,0.5,0.5)); } for(int i=0;i<12;i++) { Rect3 base(Vector3(0,0,0),Vector3(1,1,1)); Vector3 a,b; base.get_edge(i,a,b); lines.push_back(a); lines.push_back(b); } Array d; d.resize(VS::ARRAY_MAX); inner_mat = VisualServer::get_singleton()->fixed_material_create(); VisualServer::get_singleton()->fixed_material_set_param(inner_mat,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0.7,0.7,1.0,0.3)); VisualServer::get_singleton()->material_set_flag(inner_mat,VS::MATERIAL_FLAG_ONTOP,true); VisualServer::get_singleton()->material_set_flag(inner_mat,VS::MATERIAL_FLAG_UNSHADED,true); VisualServer::get_singleton()->fixed_material_set_flag( inner_mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA, true ); d[VS::ARRAY_VERTEX]=triangles; VisualServer::get_singleton()->mesh_add_surface(selection_mesh,VS::PRIMITIVE_TRIANGLES,d); VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh,0,inner_mat); outer_mat = VisualServer::get_singleton()->fixed_material_create(); VisualServer::get_singleton()->fixed_material_set_param(outer_mat,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0.7,0.7,1.0,0.8)); VisualServer::get_singleton()->material_set_line_width(outer_mat,3.0); VisualServer::get_singleton()->material_set_flag(outer_mat,VS::MATERIAL_FLAG_ONTOP,true); VisualServer::get_singleton()->material_set_flag(outer_mat,VS::MATERIAL_FLAG_UNSHADED,true); VisualServer::get_singleton()->fixed_material_set_flag( outer_mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA, true ); d[VS::ARRAY_VERTEX]=lines; VisualServer::get_singleton()->mesh_add_surface(selection_mesh,VS::PRIMITIVE_LINES,d); VisualServer::get_singleton()->mesh_surface_set_material(selection_mesh,1,outer_mat); inner_mat_dup = VisualServer::get_singleton()->fixed_material_create(); VisualServer::get_singleton()->fixed_material_set_param(inner_mat_dup,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(1.0,0.7,0.7,0.3)); VisualServer::get_singleton()->material_set_flag(inner_mat_dup,VS::MATERIAL_FLAG_ONTOP,true); VisualServer::get_singleton()->material_set_flag(inner_mat_dup,VS::MATERIAL_FLAG_UNSHADED,true); VisualServer::get_singleton()->fixed_material_set_flag( inner_mat_dup, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA, true ); d[VS::ARRAY_VERTEX]=triangles; VisualServer::get_singleton()->mesh_add_surface(duplicate_mesh,VS::PRIMITIVE_TRIANGLES,d); VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh,0,inner_mat_dup); outer_mat_dup = VisualServer::get_singleton()->fixed_material_create(); VisualServer::get_singleton()->fixed_material_set_param(outer_mat_dup,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(1.0,0.7,0.7,0.8)); VisualServer::get_singleton()->material_set_line_width(outer_mat_dup,3.0); VisualServer::get_singleton()->material_set_flag(outer_mat_dup,VS::MATERIAL_FLAG_ONTOP,true); VisualServer::get_singleton()->material_set_flag(outer_mat_dup,VS::MATERIAL_FLAG_UNSHADED,true); VisualServer::get_singleton()->fixed_material_set_flag( outer_mat_dup, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA, true ); d[VS::ARRAY_VERTEX]=lines; VisualServer::get_singleton()->mesh_add_surface(duplicate_mesh,VS::PRIMITIVE_LINES,d); VisualServer::get_singleton()->mesh_surface_set_material(duplicate_mesh,1,outer_mat_dup); } selection.active=false; updating=false; }
void CubeMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; float onethird = 1.0 / 3.0; float twothirds = 2.0 / 3.0; Vector3 start_pos = size * -0.5; // set our bounding box PoolVector<Vector3> points; PoolVector<Vector3> normals; PoolVector<float> tangents; PoolVector<Vector2> uvs; PoolVector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ tangents.push_back(m_x); \ tangents.push_back(m_y); \ tangents.push_back(m_z); \ tangents.push_back(m_d); // front + back y = start_pos.y; thisrow = point; prevrow = 0; for (j = 0; j <= subdivide_h + 1; j++) { x = start_pos.x; for (i = 0; i <= subdivide_w + 1; i++) { float u = i; float v = j; u /= (3.0 * (subdivide_w + 1.0)); v /= (2.0 * (subdivide_h + 1.0)); // front points.push_back(Vector3(x, -y, -start_pos.z)); // double negative on the Z! normals.push_back(Vector3(0.0, 0.0, 1.0)); ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(u, v)); point++; // back points.push_back(Vector3(-x, -y, start_pos.z)); normals.push_back(Vector3(0.0, 0.0, -1.0)); ADD_TANGENT(1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(twothirds + u, v)); point++; if (i > 0 && j > 0) { int i2 = i * 2; // front indices.push_back(prevrow + i2 - 2); indices.push_back(prevrow + i2); indices.push_back(thisrow + i2 - 2); indices.push_back(prevrow + i2); indices.push_back(thisrow + i2); indices.push_back(thisrow + i2 - 2); // back indices.push_back(prevrow + i2 - 1); indices.push_back(prevrow + i2 + 1); indices.push_back(thisrow + i2 - 1); indices.push_back(prevrow + i2 + 1); indices.push_back(thisrow + i2 + 1); indices.push_back(thisrow + i2 - 1); }; x += size.x / (subdivide_w + 1.0); }; y += size.y / (subdivide_h + 1.0); prevrow = thisrow; thisrow = point; }; // left + right y = start_pos.y; thisrow = point; prevrow = 0; for (j = 0; j <= (subdivide_h + 1); j++) { z = start_pos.z; for (i = 0; i <= (subdivide_d + 1); i++) { float u = i; float v = j; u /= (3.0 * (subdivide_d + 1.0)); v /= (2.0 * (subdivide_h + 1.0)); // right points.push_back(Vector3(-start_pos.x, -y, -z)); normals.push_back(Vector3(1.0, 0.0, 0.0)); ADD_TANGENT(0.0, 0.0, 1.0, -1.0); uvs.push_back(Vector2(onethird + u, v)); point++; // left points.push_back(Vector3(start_pos.x, -y, z)); normals.push_back(Vector3(-1.0, 0.0, 0.0)); ADD_TANGENT(0.0, 0.0, -1.0, -1.0); uvs.push_back(Vector2(u, 0.5 + v)); point++; if (i > 0 && j > 0) { int i2 = i * 2; // right indices.push_back(prevrow + i2 - 2); indices.push_back(prevrow + i2); indices.push_back(thisrow + i2 - 2); indices.push_back(prevrow + i2); indices.push_back(thisrow + i2); indices.push_back(thisrow + i2 - 2); // left indices.push_back(prevrow + i2 - 1); indices.push_back(prevrow + i2 + 1); indices.push_back(thisrow + i2 - 1); indices.push_back(prevrow + i2 + 1); indices.push_back(thisrow + i2 + 1); indices.push_back(thisrow + i2 - 1); }; z += size.z / (subdivide_d + 1.0); }; y += size.y / (subdivide_h + 1.0); prevrow = thisrow; thisrow = point; }; // top + bottom z = start_pos.z; thisrow = point; prevrow = 0; for (j = 0; j <= (subdivide_d + 1); j++) { x = start_pos.x; for (i = 0; i <= (subdivide_w + 1); i++) { float u = i; float v = j; u /= (3.0 * (subdivide_w + 1.0)); v /= (2.0 * (subdivide_d + 1.0)); // top points.push_back(Vector3(-x, -start_pos.y, -z)); normals.push_back(Vector3(0.0, 1.0, 0.0)); ADD_TANGENT(1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(onethird + u, 0.5 + v)); point++; // bottom points.push_back(Vector3(x, start_pos.y, -z)); normals.push_back(Vector3(0.0, -1.0, 0.0)); ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); uvs.push_back(Vector2(twothirds + u, 0.5 + v)); point++; if (i > 0 && j > 0) { int i2 = i * 2; // top indices.push_back(prevrow + i2 - 2); indices.push_back(prevrow + i2); indices.push_back(thisrow + i2 - 2); indices.push_back(prevrow + i2); indices.push_back(thisrow + i2); indices.push_back(thisrow + i2 - 2); // bottom indices.push_back(prevrow + i2 - 1); indices.push_back(prevrow + i2 + 1); indices.push_back(thisrow + i2 - 1); indices.push_back(prevrow + i2 + 1); indices.push_back(thisrow + i2 + 1); indices.push_back(thisrow + i2 - 1); }; x += size.x / (subdivide_w + 1.0); }; z += size.z / (subdivide_d + 1.0); prevrow = thisrow; thisrow = point; }; p_arr[VS::ARRAY_VERTEX] = points; p_arr[VS::ARRAY_NORMAL] = normals; p_arr[VS::ARRAY_TANGENT] = tangents; p_arr[VS::ARRAY_TEX_UV] = uvs; p_arr[VS::ARRAY_INDEX] = indices; }
Variant _jobject_to_variant(JNIEnv *env, jobject obj) { if (obj == NULL) { return Variant(); } jclass c = env->GetObjectClass(obj); bool array; String name = _get_class_name(env, c, &array); //print_line("name is " + name + ", array "+Variant(array)); print_line("ARGNAME: " + name); if (name == "java.lang.String") { return String::utf8(env->GetStringUTFChars((jstring)obj, NULL)); }; if (name == "[Ljava.lang.String;") { jobjectArray arr = (jobjectArray)obj; int stringCount = env->GetArrayLength(arr); //print_line("String array! " + String::num(stringCount)); PoolVector<String> sarr; for (int i = 0; i < stringCount; i++) { jstring string = (jstring)env->GetObjectArrayElement(arr, i); sarr.push_back(String::utf8(env->GetStringUTFChars(string, NULL))); env->DeleteLocalRef(string); } return sarr; }; if (name == "java.lang.Boolean") { jmethodID boolValue = env->GetMethodID(c, "booleanValue", "()Z"); bool ret = env->CallBooleanMethod(obj, boolValue); return ret; }; if (name == "java.lang.Integer") { jclass nclass = env->FindClass("java/lang/Number"); jmethodID intValue = env->GetMethodID(nclass, "intValue", "()I"); int ret = env->CallIntMethod(obj, intValue); return ret; }; if (name == "[I") { jintArray arr = (jintArray)obj; int fCount = env->GetArrayLength(arr); PoolVector<int> sarr; sarr.resize(fCount); PoolVector<int>::Write w = sarr.write(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); w = PoolVector<int>::Write(); return sarr; }; if (name == "[B") { jbyteArray arr = (jbyteArray)obj; int fCount = env->GetArrayLength(arr); PoolVector<uint8_t> sarr; sarr.resize(fCount); PoolVector<uint8_t>::Write w = sarr.write(); env->GetByteArrayRegion(arr, 0, fCount, reinterpret_cast<signed char *>(w.ptr())); w = PoolVector<uint8_t>::Write(); return sarr; }; if (name == "java.lang.Float" || name == "java.lang.Double") { jclass nclass = env->FindClass("java/lang/Number"); jmethodID doubleValue = env->GetMethodID(nclass, "doubleValue", "()D"); double ret = env->CallDoubleMethod(obj, doubleValue); return ret; }; if (name == "[D") { jdoubleArray arr = (jdoubleArray)obj; int fCount = env->GetArrayLength(arr); PoolRealArray sarr; sarr.resize(fCount); PoolRealArray::Write w = sarr.write(); for (int i = 0; i < fCount; i++) { double n; env->GetDoubleArrayRegion(arr, i, 1, &n); w.ptr()[i] = n; }; return sarr; }; if (name == "[F") { jfloatArray arr = (jfloatArray)obj; int fCount = env->GetArrayLength(arr); PoolRealArray sarr; sarr.resize(fCount); PoolRealArray::Write w = sarr.write(); for (int i = 0; i < fCount; i++) { float n; env->GetFloatArrayRegion(arr, i, 1, &n); w.ptr()[i] = n; }; return sarr; }; if (name == "[Ljava.lang.Object;") { jobjectArray arr = (jobjectArray)obj; int objCount = env->GetArrayLength(arr); Array varr; for (int i = 0; i < objCount; i++) { jobject jobj = env->GetObjectArrayElement(arr, i); Variant v = _jobject_to_variant(env, jobj); varr.push_back(v); env->DeleteLocalRef(jobj); } return varr; }; if (name == "java.util.HashMap" || name == "org.godotengine.godot.Dictionary") { Dictionary ret; jclass oclass = c; jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;"); jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys); PoolStringArray keys = _jobject_to_variant(env, arr); env->DeleteLocalRef(arr); jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;"); arr = (jobjectArray)env->CallObjectMethod(obj, get_values); Array vals = _jobject_to_variant(env, arr); env->DeleteLocalRef(arr); //print_line("adding " + String::num(keys.size()) + " to Dictionary!"); for (int i = 0; i < keys.size(); i++) { ret[keys[i]] = vals[i]; }; return ret; }; env->DeleteLocalRef(c); return Variant(); }
bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { if (_is_generated()) return false; String sname = p_name; if (p_name == "blend_shape/names") { PoolVector<String> sk; for (int i = 0; i < blend_shapes.size(); i++) sk.push_back(blend_shapes[i]); r_ret = sk; return true; } else if (p_name == "blend_shape/mode") { r_ret = get_blend_shape_mode(); return true; } else if (sname.begins_with("surface_")) { int sl = sname.find("/"); if (sl == -1) return false; int idx = sname.substr(8, sl - 8).to_int() - 1; String what = sname.get_slicec('/', 1); if (what == "material") r_ret = surface_get_material(idx); else if (what == "name") r_ret = surface_get_name(idx); return true; } else if (!sname.begins_with("surfaces")) return false; int idx = sname.get_slicec('/', 1).to_int(); ERR_FAIL_INDEX_V(idx, surfaces.size(), false); Dictionary d; d["array_data"] = VS::get_singleton()->mesh_surface_get_array(mesh, idx); d["vertex_count"] = VS::get_singleton()->mesh_surface_get_array_len(mesh, idx); d["array_index_data"] = VS::get_singleton()->mesh_surface_get_index_array(mesh, idx); d["index_count"] = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, idx); d["primitive"] = VS::get_singleton()->mesh_surface_get_primitive_type(mesh, idx); d["format"] = VS::get_singleton()->mesh_surface_get_format(mesh, idx); d["aabb"] = VS::get_singleton()->mesh_surface_get_aabb(mesh, idx); Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx); Array arr; for (int i = 0; i < skel_aabb.size(); i++) { arr[i] = skel_aabb[i]; } d["skeleton_aabb"] = arr; Vector<PoolVector<uint8_t> > blend_shape_data = VS::get_singleton()->mesh_surface_get_blend_shapes(mesh, idx); Array md; for (int i = 0; i < blend_shape_data.size(); i++) { md.push_back(blend_shape_data[i]); } d["blend_shape_data"] = md; Ref<Material> m = surface_get_material(idx); if (m.is_valid()) d["material"] = m; String n = surface_get_name(idx); if (n != "") d["name"] = n; r_ret = d; return true; }
void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_self, const uint8_t p_data) { PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self; self->push_back(p_data); }
void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_self, const godot_color *p_data) { PoolVector<Color> *self = (PoolVector<Color> *)p_self; Color &s = *(Color *)p_data; self->push_back(s); }
void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressSource p_source) { if (p_image->get_format() >= Image::FORMAT_BPTC_RGBA) return; //do not compress, already compressed int w = p_image->get_width(); int h = p_image->get_height(); bool is_ldr = (p_image->get_format() <= Image::FORMAT_RGBA8); bool is_hdr = (p_image->get_format() == Image::FORMAT_RGBH); if (!is_ldr && !is_hdr) { return; // Not a usable source format } cvtt::Options options; uint32_t flags = cvtt::Flags::Fastest; if (p_lossy_quality > 0.85) flags = cvtt::Flags::Ultra; else if (p_lossy_quality > 0.75) flags = cvtt::Flags::Better; else if (p_lossy_quality > 0.55) flags = cvtt::Flags::Default; else if (p_lossy_quality > 0.35) flags = cvtt::Flags::Fast; else if (p_lossy_quality > 0.15) flags = cvtt::Flags::Faster; flags |= cvtt::Flags::BC7_RespectPunchThrough; if (p_source == Image::COMPRESS_SOURCE_NORMAL) { flags |= cvtt::Flags::Uniform; } Image::Format target_format = Image::FORMAT_BPTC_RGBA; bool is_signed = false; if (is_hdr) { PoolVector<uint8_t>::Read rb = p_image->get_data().read(); const uint16_t *source_data = reinterpret_cast<const uint16_t *>(&rb[0]); int pixel_element_count = w * h * 3; for (int i = 0; i < pixel_element_count; i++) { if ((source_data[i] & 0x8000) != 0 && (source_data[i] & 0x7fff) != 0) { is_signed = true; break; } } target_format = is_signed ? Image::FORMAT_BPTC_RGBF : Image::FORMAT_BPTC_RGBFU; } else { p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert } PoolVector<uint8_t>::Read rb = p_image->get_data().read(); PoolVector<uint8_t> data; int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps()); int mm_count = p_image->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0; data.resize(target_size); int shift = Image::get_format_pixel_rshift(target_format); PoolVector<uint8_t>::Write wb = data.write(); int dst_ofs = 0; CVTTCompressionJobQueue job_queue; job_queue.job_params.is_hdr = is_hdr; job_queue.job_params.is_signed = is_signed; job_queue.job_params.options = options; job_queue.job_params.bytes_per_pixel = is_hdr ? 6 : 4; #ifdef NO_THREADS int num_job_threads = 0; #else int num_job_threads = OS::get_singleton()->can_use_threads() ? (OS::get_singleton()->get_processor_count() - 1) : 0; #endif PoolVector<CVTTCompressionRowTask> tasks; for (int i = 0; i <= mm_count; i++) { int bw = w % 4 != 0 ? w + (4 - w % 4) : w; int bh = h % 4 != 0 ? h + (4 - h % 4) : h; int src_ofs = p_image->get_mipmap_offset(i); const uint8_t *in_bytes = &rb[src_ofs]; uint8_t *out_bytes = &wb[dst_ofs]; for (int y_start = 0; y_start < h; y_start += 4) { int y_end = y_start + 4; CVTTCompressionRowTask row_task; row_task.width = w; row_task.height = h; row_task.y_start = y_start; row_task.in_mm_bytes = in_bytes; row_task.out_mm_bytes = out_bytes; if (num_job_threads > 0) { tasks.push_back(row_task); } else { _digest_row_task(job_queue.job_params, row_task); } out_bytes += 16 * (bw / 4); } dst_ofs += (MAX(4, bw) * MAX(4, bh)) >> shift; w = MAX(w / 2, 1); h = MAX(h / 2, 1); } if (num_job_threads > 0) { PoolVector<Thread *> threads; threads.resize(num_job_threads); PoolVector<Thread *>::Write threads_wb = threads.write(); PoolVector<CVTTCompressionRowTask>::Read tasks_rb = tasks.read(); job_queue.job_tasks = &tasks_rb[0]; job_queue.current_task = 0; job_queue.num_tasks = static_cast<uint32_t>(tasks.size()); for (int i = 0; i < num_job_threads; i++) { threads_wb[i] = Thread::create(_digest_job_queue, &job_queue); } _digest_job_queue(&job_queue); for (int i = 0; i < num_job_threads; i++) { Thread::wait_to_finish(threads_wb[i]); memdelete(threads_wb[i]); } } p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); }
void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_self, const godot_string *p_data) { PoolVector<String> *self = (PoolVector<String> *)p_self; String &s = *(String *)p_data; self->push_back(s); }
void EditorFileDialog::_action_pressed() { if (mode == MODE_OPEN_FILES) { String fbase = dir_access->get_current_dir(); PoolVector<String> files; for (int i = 0; i < item_list->get_item_count(); i++) { if (item_list->is_selected(i)) files.push_back(fbase.plus_file(item_list->get_item_text(i))); } if (files.size()) { _save_to_recent(); emit_signal("files_selected", files); hide(); } return; } String f = dir_access->get_current_dir().plus_file(file->get_text()); if ((mode == MODE_OPEN_ANY || mode == MODE_OPEN_FILE) && dir_access->file_exists(f)) { _save_to_recent(); emit_signal("file_selected", f); hide(); } else if (mode == MODE_OPEN_ANY || mode == MODE_OPEN_DIR) { String path = dir_access->get_current_dir(); path = path.replace("\\", "/"); for (int i = 0; i < item_list->get_item_count(); i++) { if (item_list->is_selected(i)) { Dictionary d = item_list->get_item_metadata(i); if (d["dir"]) { path = path.plus_file(d["name"]); break; } } } _save_to_recent(); emit_signal("dir_selected", path); hide(); } if (mode == MODE_SAVE_FILE) { bool valid = false; if (filter->get_selected() == filter->get_item_count() - 1) { valid = true; //match none } else if (filters.size() > 1 && filter->get_selected() == 0) { // match all filters for (int i = 0; i < filters.size(); i++) { String flt = filters[i].get_slice(";", 0); for (int j = 0; j < flt.get_slice_count(","); j++) { String str = flt.get_slice(",", j).strip_edges(); if (f.match(str)) { valid = true; break; } } if (valid) break; } } else { int idx = filter->get_selected(); if (filters.size() > 1) idx--; if (idx >= 0 && idx < filters.size()) { String flt = filters[idx].get_slice(";", 0); int filterSliceCount = flt.get_slice_count(","); for (int j = 0; j < filterSliceCount; j++) { String str = (flt.get_slice(",", j).strip_edges()); if (f.match(str)) { valid = true; break; } } if (!valid && filterSliceCount > 0) { String str = (flt.get_slice(",", 0).strip_edges()); f += str.substr(1, str.length() - 1); _request_single_thumbnail(get_current_dir().plus_file(f.get_file())); file->set_text(f.get_file()); valid = true; } } else { valid = true; } } if (!valid) { exterr->popup_centered_minsize(Size2(250, 80) * EDSCALE); return; } if (dir_access->file_exists(f) && !disable_overwrite_warning) { confirm_save->set_text(TTR("File Exists, Overwrite?")); confirm_save->popup_centered(Size2(200, 80)); } else { _save_to_recent(); emit_signal("file_selected", f); hide(); } } }
void CPUParticles2D::_update_mesh_texture() { Size2 tex_size; if (texture.is_valid()) { tex_size = texture->get_size(); } else { tex_size = Size2(1, 1); } PoolVector<Vector2> vertices; vertices.push_back(-tex_size * 0.5); vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0)); vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, tex_size.y)); vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y)); PoolVector<Vector2> uvs; uvs.push_back(Vector2(0, 0)); uvs.push_back(Vector2(1, 0)); uvs.push_back(Vector2(1, 1)); uvs.push_back(Vector2(0, 1)); PoolVector<Color> colors; colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); PoolVector<int> indices; indices.push_back(0); indices.push_back(1); indices.push_back(2); indices.push_back(2); indices.push_back(3); indices.push_back(0); Array arr; arr.resize(VS::ARRAY_MAX); arr[VS::ARRAY_VERTEX] = vertices; arr[VS::ARRAY_TEX_UV] = uvs; arr[VS::ARRAY_COLOR] = colors; arr[VS::ARRAY_INDEX] = indices; VS::get_singleton()->mesh_clear(mesh); VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLES, arr); }
void FileDialog::_action_pressed() { if (mode == MODE_OPEN_FILES) { TreeItem *ti = tree->get_next_selected(NULL); String fbase = dir_access->get_current_dir(); PoolVector<String> files; while (ti) { files.push_back(fbase.plus_file(ti->get_text(0))); ti = tree->get_next_selected(ti); } if (files.size()) { emit_signal("files_selected", files); hide(); } return; } String f = dir_access->get_current_dir().plus_file(file->get_text()); if ((mode == MODE_OPEN_ANY || mode == MODE_OPEN_FILE) && dir_access->file_exists(f)) { emit_signal("file_selected", f); hide(); } else if (mode == MODE_OPEN_ANY || mode == MODE_OPEN_DIR) { String path = dir_access->get_current_dir(); path = path.replace("\\", "/"); TreeItem *item = tree->get_selected(); if (item) { Dictionary d = item->get_metadata(0); if (d["dir"] && d["name"] != "..") { path = path.plus_file(d["name"]); } } emit_signal("dir_selected", path); hide(); } if (mode == MODE_SAVE_FILE) { bool valid = false; if (filter->get_selected() == filter->get_item_count() - 1) { valid = true; // match none } else if (filters.size() > 1 && filter->get_selected() == 0) { // match all filters for (int i = 0; i < filters.size(); i++) { String flt = filters[i].get_slice(";", 0); for (int j = 0; j < flt.get_slice_count(","); j++) { String str = flt.get_slice(",", j).strip_edges(); if (f.match(str)) { valid = true; break; } } if (valid) break; } } else { int idx = filter->get_selected(); if (filters.size() > 1) idx--; if (idx >= 0 && idx < filters.size()) { String flt = filters[idx].get_slice(";", 0); int filterSliceCount = flt.get_slice_count(","); for (int j = 0; j < filterSliceCount; j++) { String str = (flt.get_slice(",", j).strip_edges()); if (f.match(str)) { valid = true; break; } } if (!valid && filterSliceCount > 0) { String str = (flt.get_slice(",", 0).strip_edges()); f += str.substr(1, str.length() - 1); file->set_text(f.get_file()); valid = true; } } else { valid = true; } } if (!valid) { exterr->popup_centered_minsize(Size2(250, 80)); return; } if (dir_access->file_exists(f)) { confirm_save->set_text(RTR("File Exists, Overwrite?")); confirm_save->popup_centered(Size2(200, 80)); } else { emit_signal("file_selected", f); hide(); } } }
void _create_body_shape_data() { VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); // SEGMENT { PoolVector<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); } } Ref<Image> image = memnew(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->segment_shape_create(); 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 { PoolVector<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); } } Ref<Image> image = memnew(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->circle_shape_create(); ps->shape_set_data(circle_shape, 16); body_shape_data[Physics2DServer::SHAPE_CIRCLE].shape = circle_shape; } // BOX { PoolVector<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); } } Ref<Image> image = memnew(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->rectangle_shape_create(); ps->shape_set_data(rectangle_shape, Vector2(16, 16)); body_shape_data[Physics2DServer::SHAPE_RECTANGLE].shape = rectangle_shape; } // CAPSULE { PoolVector<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); } } Ref<Image> image = memnew(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->capsule_shape_create(); ps->shape_set_data(capsule_shape, Vector2(16, 32)); body_shape_data[Physics2DServer::SHAPE_CAPSULE].shape = capsule_shape; } // CONVEX { Ref<Image> image = memnew(Image(convex_png)); body_shape_data[Physics2DServer::SHAPE_CONVEX_POLYGON].image = vs->texture_create_from_image(image); RID convex_polygon_shape = ps->convex_polygon_shape_create(); PoolVector<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_CONVEX_POLYGON].shape = convex_polygon_shape; } }
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { print_line("attempt to call " + String(p_method)); r_error.error = Variant::CallError::CALL_OK; Map<StringName, MethodData>::Element *E = method_map.find(p_method); if (!E) { print_line("no exists"); r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } int ac = E->get().argtypes.size(); if (ac < p_argcount) { print_line("fewargs"); r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = ac; return Variant(); } if (ac > p_argcount) { print_line("manyargs"); r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = ac; return Variant(); } for (int i = 0; i < p_argcount; i++) { if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) { r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = i; r_error.expected = E->get().argtypes[i]; } } jvalue *v = NULL; if (p_argcount) { v = (jvalue *)alloca(sizeof(jvalue) * p_argcount); } for (int i = 0; i < p_argcount; i++) { switch (E->get().argtypes[i]) { case Variant::BOOL: { v[i].z = *p_args[i]; } break; case Variant::INT: { v[i].i = *p_args[i]; } break; case Variant::REAL: { v[i].f = *p_args[i]; } break; case Variant::STRING: { String s = *p_args[i]; jstring jStr = env->NewStringUTF(s.utf8().get_data()); v[i].l = jStr; } break; case Variant::STRING_ARRAY: { PoolVector<String> sarray = *p_args[i]; jobjectArray arr = env->NewObjectArray(sarray.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int j = 0; j < sarray.size(); j++) { env->SetObjectArrayElement(arr, j, env->NewStringUTF(sarray[i].utf8().get_data())); } v[i].l = arr; } break; case Variant::INT_ARRAY: { PoolVector<int> array = *p_args[i]; jintArray arr = env->NewIntArray(array.size()); PoolVector<int>::Read r = array.read(); env->SetIntArrayRegion(arr, 0, array.size(), r.ptr()); v[i].l = arr; } break; case Variant::REAL_ARRAY: { PoolVector<float> array = *p_args[i]; jfloatArray arr = env->NewFloatArray(array.size()); PoolVector<float>::Read r = array.read(); env->SetFloatArrayRegion(arr, 0, array.size(), r.ptr()); v[i].l = arr; } break; default: { ERR_FAIL_V(Variant()); } break; } } print_line("calling method!!"); Variant ret; switch (E->get().ret_type) { case Variant::NIL: { print_line("call void"); env->CallVoidMethodA(instance, E->get().method, v); } break; case Variant::BOOL: { ret = env->CallBooleanMethodA(instance, E->get().method, v); print_line("call bool"); } break; case Variant::INT: { ret = env->CallIntMethodA(instance, E->get().method, v); print_line("call int"); } break; case Variant::REAL: { ret = env->CallFloatMethodA(instance, E->get().method, v); } break; case Variant::STRING: { jobject o = env->CallObjectMethodA(instance, E->get().method, v); String singname = env->GetStringUTFChars((jstring)o, NULL); } break; case Variant::STRING_ARRAY: { jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v); int stringCount = env->GetArrayLength(arr); PoolVector<String> sarr; for (int i = 0; i < stringCount; i++) { jstring string = (jstring)env->GetObjectArrayElement(arr, i); const char *rawString = env->GetStringUTFChars(string, 0); sarr.push_back(String(rawString)); } ret = sarr; } break; case Variant::INT_ARRAY: { jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v); int fCount = env->GetArrayLength(arr); PoolVector<int> sarr; sarr.resize(fCount); PoolVector<int>::Write w = sarr.write(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); w = PoolVector<int>::Write(); ret = sarr; } break; case Variant::REAL_ARRAY: { jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v); int fCount = env->GetArrayLength(arr); PoolVector<float> sarr; sarr.resize(fCount); PoolVector<float>::Write w = sarr.write(); env->GetFloatArrayRegion(arr, 0, fCount, w.ptr()); w = PoolVector<float>::Write(); ret = sarr; } break; default: { print_line("failure.."); ERR_FAIL_V(Variant()); } break; } print_line("success"); return ret; }
static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, PoolVector<Face3> &p_faces) { ERR_FAIL_INDEX(x, len_x); ERR_FAIL_INDEX(y, len_y); ERR_FAIL_INDEX(z, len_z); if (p_cell_status[x][y][z] & _CELL_EXTERIOR) return; /* static const Vector3 vertices[8]={ Vector3(0,0,0), Vector3(0,0,1), Vector3(0,1,0), Vector3(0,1,1), Vector3(1,0,0), Vector3(1,0,1), Vector3(1,1,0), Vector3(1,1,1), }; */ #define vert(m_idx) Vector3((m_idx & 4) >> 2, (m_idx & 2) >> 1, m_idx & 1) static const uint8_t indices[6][4] = { { 7, 6, 4, 5 }, { 7, 3, 2, 6 }, { 7, 5, 1, 3 }, { 0, 2, 3, 1 }, { 0, 1, 5, 4 }, { 0, 4, 6, 2 }, }; /* {0,1,2,3}, {0,1,4,5}, {0,2,4,6}, {4,5,6,7}, {2,3,7,6}, {1,3,5,7}, {0,2,3,1}, {0,1,5,4}, {0,4,6,2}, {7,6,4,5}, {7,3,2,6}, {7,5,1,3}, */ for (int i = 0; i < 6; i++) { Vector3 face_points[4]; int disp_x = x + ((i % 3) == 0 ? ((i < 3) ? 1 : -1) : 0); int disp_y = y + (((i - 1) % 3) == 0 ? ((i < 3) ? 1 : -1) : 0); int disp_z = z + (((i - 2) % 3) == 0 ? ((i < 3) ? 1 : -1) : 0); bool plot = false; if (disp_x < 0 || disp_x >= len_x) plot = true; if (disp_y < 0 || disp_y >= len_y) plot = true; if (disp_z < 0 || disp_z >= len_z) plot = true; if (!plot && (p_cell_status[disp_x][disp_y][disp_z] & _CELL_EXTERIOR)) plot = true; if (!plot) continue; for (int j = 0; j < 4; j++) face_points[j] = vert(indices[i][j]) + Vector3(x, y, z); p_faces.push_back( Face3( face_points[0], face_points[1], face_points[2])); p_faces.push_back( Face3( face_points[2], face_points[3], face_points[0])); } }
void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_self, const godot_vector3 *p_data) { PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self; Vector3 &s = *(Vector3 *)p_data; self->push_back(s); }
static PoolVector<uint8_t> _lossless_pack_png(const Ref<Image> &p_image) { Ref<Image> img = p_image->duplicate(); if (img->is_compressed()) img->decompress(); ERR_FAIL_COND_V(img->is_compressed(), PoolVector<uint8_t>()); png_structp png_ptr; png_infop info_ptr; png_bytep *row_pointers; /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); ERR_FAIL_COND_V(!png_ptr, PoolVector<uint8_t>()); info_ptr = png_create_info_struct(png_ptr); ERR_FAIL_COND_V(!info_ptr, PoolVector<uint8_t>()); if (setjmp(png_jmpbuf(png_ptr))) { ERR_FAIL_V(PoolVector<uint8_t>()); } PoolVector<uint8_t> ret; ret.push_back('P'); ret.push_back('N'); ret.push_back('G'); ret.push_back(' '); png_set_write_fn(png_ptr, &ret, _write_png_data, NULL); /* write header */ if (setjmp(png_jmpbuf(png_ptr))) { ERR_FAIL_V(PoolVector<uint8_t>()); } int pngf = 0; int cs = 0; switch (img->get_format()) { case Image::FORMAT_L8: { pngf = PNG_COLOR_TYPE_GRAY; cs = 1; } break; case Image::FORMAT_LA8: { pngf = PNG_COLOR_TYPE_GRAY_ALPHA; cs = 2; } break; case Image::FORMAT_RGB8: { pngf = PNG_COLOR_TYPE_RGB; cs = 3; } break; case Image::FORMAT_RGBA8: { pngf = PNG_COLOR_TYPE_RGB_ALPHA; cs = 4; } break; default: { if (img->detect_alpha()) { img->convert(Image::FORMAT_RGBA8); pngf = PNG_COLOR_TYPE_RGB_ALPHA; cs = 4; } else { img->convert(Image::FORMAT_RGB8); pngf = PNG_COLOR_TYPE_RGB; cs = 3; } } } int w = img->get_width(); int h = img->get_height(); png_set_IHDR(png_ptr, info_ptr, w, h, 8, pngf, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); /* write bytes */ if (setjmp(png_jmpbuf(png_ptr))) { ERR_FAIL_V(PoolVector<uint8_t>()); } PoolVector<uint8_t>::Read r = img->get_data().read(); row_pointers = (png_bytep *)memalloc(sizeof(png_bytep) * h); for (int i = 0; i < h; i++) { row_pointers[i] = (png_bytep)&r[i * w * cs]; } png_write_image(png_ptr, row_pointers); memfree(row_pointers); /* end write */ if (setjmp(png_jmpbuf(png_ptr))) { ERR_FAIL_V(PoolVector<uint8_t>()); } png_write_end(png_ptr, NULL); return ret; }
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) { const uint8_t *buf = p_buffer; int len = p_len; if (len < 4) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); } uint32_t type = decode_uint32(buf); ERR_FAIL_COND_V((type & ENCODE_MASK) >= Variant::VARIANT_MAX, ERR_INVALID_DATA); buf += 4; len -= 4; if (r_len) *r_len = 4; switch (type & ENCODE_MASK) { case Variant::NIL: { r_variant = Variant(); } break; case Variant::BOOL: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); bool val = decode_uint32(buf); r_variant = val; if (r_len) (*r_len) += 4; } break; case Variant::INT: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); if (type & ENCODE_FLAG_64) { int64_t val = decode_uint64(buf); r_variant = val; if (r_len) (*r_len) += 8; } else { int32_t val = decode_uint32(buf); r_variant = val; if (r_len) (*r_len) += 4; } } break; case Variant::REAL: { ERR_FAIL_COND_V(len < (int)4, ERR_INVALID_DATA); if (type & ENCODE_FLAG_64) { double val = decode_double(buf); r_variant = val; if (r_len) (*r_len) += 8; } else { float val = decode_float(buf); r_variant = val; if (r_len) (*r_len) += 4; } } break; case Variant::STRING: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); r_variant = str; if (r_len) { if (strlen % 4) (*r_len) += 4 - strlen % 4; (*r_len) += 4 + strlen; } } break; // math types case Variant::VECTOR2: { ERR_FAIL_COND_V(len < (int)4 * 2, ERR_INVALID_DATA); Vector2 val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); r_variant = val; if (r_len) (*r_len) += 4 * 2; } break; // 5 case Variant::RECT2: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Rect2 val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.size.x = decode_float(&buf[8]); val.size.y = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::VECTOR3: { ERR_FAIL_COND_V(len < (int)4 * 3, ERR_INVALID_DATA); Vector3 val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); r_variant = val; if (r_len) (*r_len) += 4 * 3; } break; case Variant::TRANSFORM2D: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); Transform2D val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { val.elements[i][j] = decode_float(&buf[(i * 2 + j) * 4]); } } r_variant = val; if (r_len) (*r_len) += 4 * 6; } break; case Variant::PLANE: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Plane val; val.normal.x = decode_float(&buf[0]); val.normal.y = decode_float(&buf[4]); val.normal.z = decode_float(&buf[8]); val.d = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::QUAT: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Quat val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); val.w = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::RECT3: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); Rect3 val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.position.z = decode_float(&buf[8]); val.size.x = decode_float(&buf[12]); val.size.y = decode_float(&buf[16]); val.size.z = decode_float(&buf[20]); r_variant = val; if (r_len) (*r_len) += 4 * 6; } break; case Variant::BASIS: { ERR_FAIL_COND_V(len < (int)4 * 9, ERR_INVALID_DATA); Basis val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); } } r_variant = val; if (r_len) (*r_len) += 4 * 9; } break; case Variant::TRANSFORM: { ERR_FAIL_COND_V(len < (int)4 * 12, ERR_INVALID_DATA); Transform val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); } } val.origin[0] = decode_float(&buf[36]); val.origin[1] = decode_float(&buf[40]); val.origin[2] = decode_float(&buf[44]); r_variant = val; if (r_len) (*r_len) += 4 * 12; } break; // misc types case Variant::COLOR: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Color val; val.r = decode_float(&buf[0]); val.g = decode_float(&buf[4]); val.b = decode_float(&buf[8]); val.a = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::NODE_PATH: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); if (strlen & 0x80000000) { //new format ERR_FAIL_COND_V(len < 12, ERR_INVALID_DATA); Vector<StringName> names; Vector<StringName> subnames; StringName prop; uint32_t namecount = strlen &= 0x7FFFFFFF; uint32_t subnamecount = decode_uint32(buf + 4); uint32_t flags = decode_uint32(buf + 8); len -= 12; buf += 12; int total = namecount + subnamecount; if (flags & 2) total++; if (r_len) (*r_len) += 12; for (int i = 0; i < total; i++) { ERR_FAIL_COND_V((int)len < 4, ERR_INVALID_DATA); strlen = decode_uint32(buf); int pad = 0; if (strlen % 4) pad += 4 - strlen % 4; buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen + pad > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); if (i < namecount) names.push_back(str); else if (i < namecount + subnamecount) subnames.push_back(str); else prop = str; buf += strlen + pad; len -= strlen + pad; if (r_len) (*r_len) += 4 + strlen + pad; } r_variant = NodePath(names, subnames, flags & 1, prop); } else { //old format, just a string buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); r_variant = NodePath(str); if (r_len) (*r_len) += 4 + strlen; } } break; /*case Variant::RESOURCE: { ERR_EXPLAIN("Can't marshallize resources"); ERR_FAIL_V(ERR_INVALID_DATA); //no, i'm sorry, no go } break;*/ case Variant::_RID: { r_variant = RID(); } break; case Variant::OBJECT: { r_variant = (Object *)NULL; } break; case Variant::DICTIONARY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); // bool shared = count&0x80000000; count &= 0x7FFFFFFF; buf += 4; len -= 4; if (r_len) { (*r_len) += 4; } Dictionary d; for (uint32_t i = 0; i < count; i++) { Variant key, value; int used; Error err = decode_variant(key, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; if (r_len) { (*r_len) += used; } err = decode_variant(value, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; if (r_len) { (*r_len) += used; } d[key] = value; } r_variant = d; } break; case Variant::ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); // bool shared = count&0x80000000; count &= 0x7FFFFFFF; buf += 4; len -= 4; if (r_len) { (*r_len) += 4; } Array varr; for (uint32_t i = 0; i < count; i++) { int used = 0; Variant v; Error err = decode_variant(v, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; varr.push_back(v); if (r_len) { (*r_len) += used; } } r_variant = varr; } break; // arrays case Variant::POOL_BYTE_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count > len, ERR_INVALID_DATA); PoolVector<uint8_t> data; if (count) { data.resize(count); PoolVector<uint8_t>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = buf[i]; } w = PoolVector<uint8_t>::Write(); } r_variant = data; if (r_len) { if (count % 4) (*r_len) += 4 - count % 4; (*r_len) += 4 + count; } } break; case Variant::POOL_INT_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA); PoolVector<int> data; if (count) { //const int*rbuf=(const int*)buf; data.resize(count); PoolVector<int>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = decode_uint32(&buf[i * 4]); } w = PoolVector<int>::Write(); } r_variant = Variant(data); if (r_len) { (*r_len) += 4 + count * sizeof(int); } } break; case Variant::POOL_REAL_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA); PoolVector<float> data; if (count) { //const float*rbuf=(const float*)buf; data.resize(count); PoolVector<float>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = decode_float(&buf[i * 4]); } w = PoolVector<float>::Write(); } r_variant = data; if (r_len) { (*r_len) += 4 + count * sizeof(float); } } break; case Variant::POOL_STRING_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); PoolVector<String> strings; buf += 4; len -= 4; if (r_len) (*r_len) += 4; //printf("string count: %i\n",count); for (int i = 0; i < (int)count; i++) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); //printf("loaded string: %s\n",(const char*)buf); String str; str.parse_utf8((const char *)buf, strlen); strings.push_back(str); buf += strlen; len -= strlen; if (r_len) (*r_len) += 4 + strlen; if (strlen % 4) { int pad = 4 - (strlen % 4); buf += pad; len -= pad; if (r_len) { (*r_len) += pad; } } } r_variant = strings; } break; case Variant::POOL_VECTOR2_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 2 > len, ERR_INVALID_DATA); PoolVector<Vector2> varray; if (r_len) { (*r_len) += 4; } if (count) { varray.resize(count); PoolVector<Vector2>::Write w = varray.write(); for (int i = 0; i < (int)count; i++) { w[i].x = decode_float(buf + i * 4 * 2 + 4 * 0); w[i].y = decode_float(buf + i * 4 * 2 + 4 * 1); } int adv = 4 * 2 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = varray; } break; case Variant::POOL_VECTOR3_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 3 > len, ERR_INVALID_DATA); PoolVector<Vector3> varray; if (r_len) { (*r_len) += 4; } if (count) { varray.resize(count); PoolVector<Vector3>::Write w = varray.write(); for (int i = 0; i < (int)count; i++) { w[i].x = decode_float(buf + i * 4 * 3 + 4 * 0); w[i].y = decode_float(buf + i * 4 * 3 + 4 * 1); w[i].z = decode_float(buf + i * 4 * 3 + 4 * 2); } int adv = 4 * 3 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = varray; } break; case Variant::POOL_COLOR_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 4 > len, ERR_INVALID_DATA); PoolVector<Color> carray; if (r_len) { (*r_len) += 4; } if (count) { carray.resize(count); PoolVector<Color>::Write w = carray.write(); for (int i = 0; i < (int)count; i++) { w[i].r = decode_float(buf + i * 4 * 4 + 4 * 0); w[i].g = decode_float(buf + i * 4 * 4 + 4 * 1); w[i].b = decode_float(buf + i * 4 * 4 + 4 * 2); w[i].a = decode_float(buf + i * 4 * 4 + 4 * 3); } int adv = 4 * 4 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = carray; } break; default: { ERR_FAIL_V(ERR_BUG); } } return OK; }
void CapsuleMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z, u, v, w; float onethird = 1.0 / 3.0; float twothirds = 2.0 / 3.0; // note, this has been aligned with our collision shape but I've left the descriptions as top/middle/bottom PoolVector<Vector3> points; PoolVector<Vector3> normals; PoolVector<float> tangents; PoolVector<Vector2> uvs; PoolVector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ tangents.push_back(m_x); \ tangents.push_back(m_y); \ tangents.push_back(m_z); \ tangents.push_back(m_d); /* top hemisphere */ thisrow = 0; prevrow = 0; for (j = 0; j <= (rings + 1); j++) { v = j; v /= (rings + 1); w = sin(0.5 * Math_PI * v); z = radius * cos(0.5 * Math_PI * v); for (i = 0; i <= radial_segments; i++) { u = i; u /= radial_segments; x = sin(u * (Math_PI * 2.0)); y = -cos(u * (Math_PI * 2.0)); Vector3 p = Vector3(x * radius * w, y * radius * w, z); points.push_back(p + Vector3(0.0, 0.0, 0.5 * mid_height)); normals.push_back(p.normalized()); ADD_TANGENT(y, -x, 0.0, -1.0) uvs.push_back(Vector2(u, v * onethird)); point++; if (i > 0 && j > 0) { indices.push_back(prevrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i); indices.push_back(thisrow + i - 1); }; }; prevrow = thisrow; thisrow = point; }; /* cylinder */ thisrow = point; prevrow = 0; for (j = 0; j <= (rings + 1); j++) { v = j; v /= (rings + 1); z = mid_height * v; z = (mid_height * 0.5) - z; for (i = 0; i <= radial_segments; i++) { u = i; u /= radial_segments; x = sin(u * (Math_PI * 2.0)); y = -cos(u * (Math_PI * 2.0)); Vector3 p = Vector3(x * radius, y * radius, z); points.push_back(p); normals.push_back(Vector3(x, y, 0.0)); ADD_TANGENT(y, -x, 0.0, -1.0) uvs.push_back(Vector2(u, onethird + (v * onethird))); point++; if (i > 0 && j > 0) { indices.push_back(prevrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i); indices.push_back(thisrow + i - 1); }; }; prevrow = thisrow; thisrow = point; }; /* bottom hemisphere */ thisrow = point; prevrow = 0; for (j = 0; j <= (rings + 1); j++) { v = j; v /= (rings + 1); v += 1.0; w = sin(0.5 * Math_PI * v); z = radius * cos(0.5 * Math_PI * v); for (i = 0; i <= radial_segments; i++) { float u = i; u /= radial_segments; x = sin(u * (Math_PI * 2.0)); y = -cos(u * (Math_PI * 2.0)); Vector3 p = Vector3(x * radius * w, y * radius * w, z); points.push_back(p + Vector3(0.0, 0.0, -0.5 * mid_height)); normals.push_back(p.normalized()); ADD_TANGENT(y, -x, 0.0, -1.0) uvs.push_back(Vector2(u, twothirds + ((v - 1.0) * onethird))); point++; if (i > 0 && j > 0) { indices.push_back(prevrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i); indices.push_back(thisrow + i - 1); }; }; prevrow = thisrow; thisrow = point; }; p_arr[VS::ARRAY_VERTEX] = points; p_arr[VS::ARRAY_NORMAL] = normals; p_arr[VS::ARRAY_TANGENT] = tangents; p_arr[VS::ARRAY_TEX_UV] = uvs; p_arr[VS::ARRAY_INDEX] = indices; }
void CylinderMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z, u, v, radius; radius = bottom_radius > top_radius ? bottom_radius : top_radius; PoolVector<Vector3> points; PoolVector<Vector3> normals; PoolVector<float> tangents; PoolVector<Vector2> uvs; PoolVector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ tangents.push_back(m_x); \ tangents.push_back(m_y); \ tangents.push_back(m_z); \ tangents.push_back(m_d); thisrow = 0; prevrow = 0; for (j = 0; j <= (rings + 1); j++) { v = j; v /= (rings + 1); radius = top_radius + ((bottom_radius - top_radius) * v); y = height * v; y = (height * 0.5) - y; for (i = 0; i <= radial_segments; i++) { u = i; u /= radial_segments; x = sin(u * (Math_PI * 2.0)); z = cos(u * (Math_PI * 2.0)); Vector3 p = Vector3(x * radius, y, z * radius); points.push_back(p); normals.push_back(Vector3(x, 0.0, z)); ADD_TANGENT(-z, 0.0, x, -1.0) uvs.push_back(Vector2(u, v * 0.5)); point++; if (i > 0 && j > 0) { indices.push_back(prevrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i); indices.push_back(thisrow + i - 1); }; }; prevrow = thisrow; thisrow = point; }; // add top if (top_radius > 0.0) { y = height * 0.5; thisrow = point; points.push_back(Vector3(0.0, y, 0.0)); normals.push_back(Vector3(0.0, 1.0, 0.0)); ADD_TANGENT(1.0, 0.0, 0.0, 1.0) uvs.push_back(Vector2(0.25, 0.75)); point++; for (i = 0; i <= radial_segments; i++) { float r = i; r /= radial_segments; x = sin(r * (Math_PI * 2.0)); z = cos(r * (Math_PI * 2.0)); u = ((x + 1.0) * 0.25); v = 0.5 + ((z + 1.0) * 0.25); Vector3 p = Vector3(x * top_radius, y, z * top_radius); points.push_back(p); normals.push_back(Vector3(0.0, 1.0, 0.0)); ADD_TANGENT(1.0, 0.0, 0.0, 1.0) uvs.push_back(Vector2(u, v)); point++; if (i > 0) { indices.push_back(thisrow); indices.push_back(point - 1); indices.push_back(point - 2); }; }; }; // add bottom if (bottom_radius > 0.0) { y = height * -0.5; thisrow = point; points.push_back(Vector3(0.0, y, 0.0)); normals.push_back(Vector3(0.0, -1.0, 0.0)); ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) uvs.push_back(Vector2(0.75, 0.75)); point++; for (i = 0; i <= radial_segments; i++) { float r = i; r /= radial_segments; x = sin(r * (Math_PI * 2.0)); z = cos(r * (Math_PI * 2.0)); u = 0.5 + ((x + 1.0) * 0.25); v = 1.0 - ((z + 1.0) * 0.25); Vector3 p = Vector3(x * bottom_radius, y, z * bottom_radius); points.push_back(p); normals.push_back(Vector3(0.0, -1.0, 0.0)); ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) uvs.push_back(Vector2(u, v)); point++; if (i > 0) { indices.push_back(thisrow); indices.push_back(point - 2); indices.push_back(point - 1); }; }; }; p_arr[VS::ARRAY_VERTEX] = points; p_arr[VS::ARRAY_NORMAL] = normals; p_arr[VS::ARRAY_TANGENT] = tangents; p_arr[VS::ARRAY_TEX_UV] = uvs; p_arr[VS::ARRAY_INDEX] = indices; }
void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_self, const godot_real p_data) { PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self; self->push_back(p_data); }
void SphereMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; // set our bounding box PoolVector<Vector3> points; PoolVector<Vector3> normals; PoolVector<float> tangents; PoolVector<Vector2> uvs; PoolVector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ tangents.push_back(m_x); \ tangents.push_back(m_y); \ tangents.push_back(m_z); \ tangents.push_back(m_d); thisrow = 0; prevrow = 0; for (j = 0; j <= (rings + 1); j++) { float v = j; float w; v /= (rings + 1); w = sin(Math_PI * v); y = height * (is_hemisphere ? 1.0 : 0.5) * cos(Math_PI * v); for (i = 0; i <= radial_segments; i++) { float u = i; u /= radial_segments; x = sin(u * (Math_PI * 2.0)); z = cos(u * (Math_PI * 2.0)); if (is_hemisphere && y < 0.0) { points.push_back(Vector3(x * radius * w, 0.0, z * radius * w)); normals.push_back(Vector3(0.0, -1.0, 0.0)); } else { Vector3 p = Vector3(x * radius * w, y, z * radius * w); points.push_back(p); normals.push_back(p.normalized()); }; ADD_TANGENT(-z, 0.0, x, -1.0) uvs.push_back(Vector2(u, v)); point++; if (i > 0 && j > 0) { indices.push_back(prevrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i - 1); indices.push_back(prevrow + i); indices.push_back(thisrow + i); indices.push_back(thisrow + i - 1); }; }; prevrow = thisrow; thisrow = point; }; p_arr[VS::ARRAY_VERTEX] = points; p_arr[VS::ARRAY_NORMAL] = normals; p_arr[VS::ARRAY_TANGENT] = tangents; p_arr[VS::ARRAY_TEX_UV] = uvs; p_arr[VS::ARRAY_INDEX] = indices; }