Dictionary PolygonPathFinder::_get_data() const { Dictionary d; PoolVector<Vector2> p; PoolVector<int> ind; Array connections; p.resize(points.size() - 2); connections.resize(points.size() - 2); ind.resize(edges.size() * 2); PoolVector<float> penalties; penalties.resize(points.size() - 2); { PoolVector<Vector2>::Write wp = p.write(); PoolVector<float>::Write pw = penalties.write(); for (int i = 0; i < points.size() - 2; i++) { wp[i] = points[i].pos; pw[i] = points[i].penalty; PoolVector<int> c; c.resize(points[i].connections.size()); { PoolVector<int>::Write cw = c.write(); int idx = 0; for (Set<int>::Element *E = points[i].connections.front(); E; E = E->next()) { cw[idx++] = E->get(); } } connections[i] = c; } } { PoolVector<int>::Write iw = ind.write(); int idx = 0; for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) { iw[idx++] = E->get().points[0]; iw[idx++] = E->get().points[1]; } } d["bounds"] = bounds; d["points"] = p; d["penalties"] = penalties; d["connections"] = connections; d["segments"] = ind; return d; }
RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V(!f, RES()); PoolVector<uint8_t> data; data.resize(f->get_len()); ERR_FAIL_COND_V(data.size() == 0, RES()); { PoolVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(), data.size()); } Ref<DynamicFontData> dfd; dfd.instance(); dfd->set_font_data(data); if (r_error) *r_error = OK; return dfd; }
Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { bool loop = p_options["loop"]; FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ); if (!f) { ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); } size_t len = f->get_len(); PoolVector<uint8_t> data; data.resize(len); PoolVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(), len); memdelete(f); Ref<AudioStreamOGGVorbis> ogg_stream; ogg_stream.instance(); ogg_stream->set_data(data); ogg_stream->set_loop(loop); return ResourceSaver::save(p_save_path + ".asogg", ogg_stream); }
void ColorPicker::_update_presets() { Size2 size = bt_add_preset->get_size(); preset->set_custom_minimum_size(Size2(size.width * presets.size(), size.height)); PoolVector<uint8_t> img; img.resize(size.x * presets.size() * size.y * 3); { PoolVector<uint8_t>::Write w = img.write(); for (int y = 0; y < size.y; y++) { for (int x = 0; x < size.x * presets.size(); x++) { int ofs = (y * (size.x * presets.size()) + x) * 3; w[ofs + 0] = uint8_t(CLAMP(presets[(int)x / size.x].r * 255.0, 0, 255)); w[ofs + 1] = uint8_t(CLAMP(presets[(int)x / size.x].g * 255.0, 0, 255)); w[ofs + 2] = uint8_t(CLAMP(presets[(int)x / size.x].b * 255.0, 0, 255)); } } } Ref<Image> i = memnew(Image(size.x * presets.size(), size.y, false, Image::FORMAT_RGB8, img)); Ref<ImageTexture> t; t.instance(); t->create_from_image(i); preset->set_texture(t); }
Array StreamPeer::_get_partial_data(int p_bytes) { Array ret; PoolVector<uint8_t> data; data.resize(p_bytes); if (data.size() != p_bytes) { ret.push_back(ERR_OUT_OF_MEMORY); ret.push_back(PoolVector<uint8_t>()); return ret; } PoolVector<uint8_t>::Write w = data.write(); int received; Error err = get_partial_data(&w[0], p_bytes, received); w = PoolVector<uint8_t>::Write(); if (err != OK) { data.resize(0); } else if (received != data.size()) { data.resize(received); } ret.push_back(err); ret.push_back(data); return ret; }
void VisualServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const PoolVector<Vector2> &p_shape, bool p_closed) { if (p_shape.size() < 3) { canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, p_shape); return; } PoolVector<Vector2> lines; int lc = p_shape.size() * 2; lines.resize(lc - (p_closed ? 0 : 2)); { PoolVector<Vector2>::Write w = lines.write(); PoolVector<Vector2>::Read r = p_shape.read(); int max = lc / 2; if (!p_closed) { max--; } for (int i = 0; i < max; i++) { Vector2 a = r[i]; Vector2 b = r[(i + 1) % (lc / 2)]; w[i * 2 + 0] = a; w[i * 2 + 1] = b; } } canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, lines); }
Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) return triangle_mesh; PoolVector<Vector3> faces; faces.resize(6); PoolVector<Vector3>::Write facesw = faces.write(); Rect2 final_rect = get_item_rect(); if (final_rect.size.x == 0 || final_rect.size.y == 0) return Ref<TriangleMesh>(); float pixel_size = get_pixel_size(); Vector2 vertices[4] = { (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size, (final_rect.position + final_rect.size) * pixel_size, (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size, final_rect.position * pixel_size, }; int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); if (axis != Vector3::AXIS_Z) { SWAP(x_axis, y_axis); for (int i = 0; i < 4; i++) { if (axis == Vector3::AXIS_Y) { vertices[i].y = -vertices[i].y; } else if (axis == Vector3::AXIS_X) { vertices[i].x = -vertices[i].x; } } } static const int indices[6] = { 0, 1, 2, 0, 2, 3 }; for (int j = 0; j < 6; j++) { int i = indices[j]; Vector3 vtx; vtx[x_axis] = vertices[i][0]; vtx[y_axis] = vertices[i][1]; facesw[j] = vtx; } facesw = PoolVector<Vector3>::Write(); triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); triangle_mesh->create(faces); return triangle_mesh; }
void CollisionPolygon2D::_add_to_collision_object(Object *p_obj) { if (unparenting || !can_update_body) return; CollisionObject2D *co = p_obj->cast_to<CollisionObject2D>(); ERR_FAIL_COND(!co); if (polygon.size() == 0) return; bool solids = build_mode == BUILD_SOLIDS; if (solids) { //here comes the sun, lalalala //decompose concave into multiple convex polygons and add them Vector<Vector<Vector2> > decomp = _decompose_in_convex(); shape_from = co->get_shape_count(); for (int i = 0; i < decomp.size(); i++) { Ref<ConvexPolygonShape2D> convex = memnew(ConvexPolygonShape2D); convex->set_points(decomp[i]); co->add_shape(convex, get_transform()); if (trigger) co->set_shape_as_trigger(co->get_shape_count() - 1, true); } shape_to = co->get_shape_count() - 1; if (shape_to < shape_from) { shape_from = -1; shape_to = -1; } } else { Ref<ConcavePolygonShape2D> concave = memnew(ConcavePolygonShape2D); PoolVector<Vector2> segments; segments.resize(polygon.size() * 2); PoolVector<Vector2>::Write w = segments.write(); for (int i = 0; i < polygon.size(); i++) { w[(i << 1) + 0] = polygon[i]; w[(i << 1) + 1] = polygon[(i + 1) % polygon.size()]; } w = PoolVector<Vector2>::Write(); concave->set_segments(segments); co->add_shape(concave, get_transform()); if (trigger) co->set_shape_as_trigger(co->get_shape_count() - 1, true); shape_from = co->get_shape_count() - 1; shape_to = co->get_shape_count() - 1; } //co->add_shape(shape,get_transform()); }
bool GridMap::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name == "theme") { r_ret = get_theme(); } else if (name == "cell_size") { r_ret = get_cell_size(); } else if (name == "cell_octant_size") { r_ret = get_octant_size(); } else if (name == "cell_center_x") { r_ret = get_center_x(); } else if (name == "cell_center_y") { r_ret = get_center_y(); } else if (name == "cell_center_z") { r_ret = get_center_z(); } else if (name == "cell_scale") { r_ret = cell_scale; } else if (name == "data") { Dictionary d; PoolVector<int> cells; cells.resize(cell_map.size() * 3); { PoolVector<int>::Write w = cells.write(); int i = 0; for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) { encode_uint64(E->key().key, (uint8_t *)&w[i * 3]); encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]); } } d["cells"] = cells; r_ret = d; } else if (name.begins_with("areas/")) { int which = name.get_slicec('/', 1).to_int(); String what = name.get_slicec('/', 2); if (what == "bounds") r_ret = area_get_bounds(which); else if (what == "name") r_ret = area_get_name(which); else if (what == "disable_distance") r_ret = area_get_portal_disable_distance(which); else if (what == "exterior_portal") r_ret = area_is_exterior_portal(which); else return false; } else return false; return true; }
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; }
void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) { ERR_FAIL_COND(p_packet_len < 2); PoolVector<uint8_t> out; int len = p_packet_len - 1; out.resize(len); { PoolVector<uint8_t>::Write w = out.write(); memcpy(&w[0], &p_packet[1], len); } emit_signal("network_peer_packet", p_from, out); }
void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform) { Vector<Vector3> toadd = _gen_debug_mesh_lines(); if (toadd.size()) { int base = array.size(); array.resize(base + toadd.size()); PoolVector<Vector3>::Write w = array.write(); for (int i = 0; i < toadd.size(); i++) { w[i + base] = p_xform.xform(toadd[i]); } } }
Error PacketPeer::get_packet_buffer(PoolVector<uint8_t> &r_buffer) const { const uint8_t *buffer; int buffer_size; Error err = get_packet(&buffer, buffer_size); if (err) return err; r_buffer.resize(buffer_size); if (buffer_size == 0) return OK; PoolVector<uint8_t>::Write w = r_buffer.write(); for (int i = 0; i < buffer_size; i++) w[i] = buffer[i]; return OK; }
bool GridMap::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; if (name == "theme") { r_ret = get_theme(); } else if (name == "cell_size") { r_ret = get_cell_size(); } else if (name == "cell_octant_size") { r_ret = get_octant_size(); } else if (name == "cell_center_x") { r_ret = get_center_x(); } else if (name == "cell_center_y") { r_ret = get_center_y(); } else if (name == "cell_center_z") { r_ret = get_center_z(); } else if (name == "cell_scale") { r_ret = cell_scale; } else if (name == "data") { Dictionary d; PoolVector<int> cells; cells.resize(cell_map.size() * 3); { PoolVector<int>::Write w = cells.write(); int i = 0; for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) { encode_uint64(E->key().key, (uint8_t *)&w[i * 3]); encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]); } } d["cells"] = cells; r_ret = d; } else return false; return true; }
Array StreamPeer::_get_data(int p_bytes) { Array ret; PoolVector<uint8_t> data; data.resize(p_bytes); if (data.size() != p_bytes) { ret.push_back(ERR_OUT_OF_MEMORY); ret.push_back(PoolVector<uint8_t>()); return ret; } PoolVector<uint8_t>::Write w = data.write(); Error err = get_data(&w[0], p_bytes); w = PoolVector<uint8_t>::Write(); ret.push_back(err); ret.push_back(data); return ret; }
void image_decompress_squish(Image *p_image) { int w = p_image->get_width(); int h = p_image->get_height(); Image::Format target_format = Image::FORMAT_RGBA8; PoolVector<uint8_t> data; int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0); int mm_count = p_image->get_mipmap_count(); data.resize(target_size); PoolVector<uint8_t>::Read rb = p_image->get_data().read(); PoolVector<uint8_t>::Write wb = data.write(); int squish_flags = Image::FORMAT_MAX; if (p_image->get_format() == Image::FORMAT_DXT1) { squish_flags = squish::kDxt1; } else if (p_image->get_format() == Image::FORMAT_DXT3) { squish_flags = squish::kDxt3; } else if (p_image->get_format() == Image::FORMAT_DXT5) { squish_flags = squish::kDxt5; } else if (p_image->get_format() == Image::FORMAT_RGTC_R) { squish_flags = squish::kBc4; } else if (p_image->get_format() == Image::FORMAT_RGTC_RG) { squish_flags = squish::kBc5; } else { print_line("wtf askd to decompress.. " + itos(p_image->get_format())); ERR_FAIL_COND(true); return; } int dst_ofs = 0; for (int i = 0; i <= mm_count; i++) { int src_ofs = 0, mipmap_size = 0, mipmap_w = 0, mipmap_h = 0; p_image->get_mipmap_offset_size_and_dimensions(i, src_ofs, mipmap_size, mipmap_w, mipmap_h); squish::DecompressImage(&wb[dst_ofs], mipmap_w, mipmap_h, &rb[src_ofs], squish_flags); } p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); }
PoolVector<Face3> TriangleMesh::get_faces() const { if (!valid) return PoolVector<Face3>(); PoolVector<Face3> faces; int ts = triangles.size(); faces.resize(triangles.size()); PoolVector<Face3>::Write w = faces.write(); PoolVector<Triangle>::Read r = triangles.read(); PoolVector<Vector3>::Read rv = vertices.read(); for (int i = 0; i < ts; i++) { for (int j = 0; j < 3; j++) { w[i].vertex[j] = rv[r[i].indices[j]]; } } w = PoolVector<Face3>::Write(); return faces; }
Ref<Image> SimplexNoise::get_image(int p_width, int p_height) { PoolVector<uint8_t> data; data.resize(p_width * p_height * 4); PoolVector<uint8_t>::Write wd8 = data.write(); for (int i = 0; i < p_height; i++) { for (int j = 0; j < p_width; j++) { float v = get_noise_2d(i, j); v = v * 0.5 + 0.5; // Normalize [0..1] uint8_t value = uint8_t(CLAMP(v * 255.0, 0, 255)); wd8[(i * p_width + j) * 4 + 0] = value; wd8[(i * p_width + j) * 4 + 1] = value; wd8[(i * p_width + j) * 4 + 2] = value; wd8[(i * p_width + j) * 4 + 3] = 255; } } Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_RGBA8, data)); return image; }
void CollisionPolygon::_build_polygon() { if (!parent) return; parent->shape_owner_clear_shapes(owner_id); if (polygon.size() == 0) return; Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon); if (decomp.size() == 0) return; //here comes the sun, lalalala //decompose concave into multiple convex polygons and add them for (int i = 0; i < decomp.size(); i++) { Ref<ConvexPolygonShape> convex = memnew(ConvexPolygonShape); PoolVector<Vector3> cp; int cs = decomp[i].size(); cp.resize(cs * 2); { PoolVector<Vector3>::Write w = cp.write(); int idx = 0; for (int j = 0; j < cs; j++) { Vector2 d = decomp[i][j]; w[idx++] = Vector3(d.x, d.y, depth * 0.5); w[idx++] = Vector3(d.x, d.y, -depth * 0.5); } } convex->set_points(cp); parent->shape_owner_add_shape(owner_id, convex); parent->shape_owner_set_disabled(owner_id, disabled); } }
Error read_all_file_utf8(const String &p_path, String &r_content) { PoolVector<uint8_t> sourcef; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); ERR_FAIL_COND_V(err != OK, err); int len = f->get_len(); sourcef.resize(len + 1); PoolVector<uint8_t>::Write w = sourcef.write(); int r = f->get_buffer(w.ptr(), len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); w[len] = 0; String source; if (source.parse_utf8((const char *)w.ptr())) { ERR_FAIL_V(ERR_INVALID_DATA); } r_content = source; return OK; }
Ref<ArrayMesh> Shape::get_debug_mesh() { if (debug_mesh_cache.is_valid()) return debug_mesh_cache; Vector<Vector3> lines = _gen_debug_mesh_lines(); debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh)); if (!lines.empty()) { //make mesh PoolVector<Vector3> array; array.resize(lines.size()); { PoolVector<Vector3>::Write w = array.write(); for (int i = 0; i < lines.size(); i++) { w[i] = lines[i]; } } Array arr; arr.resize(Mesh::ARRAY_MAX); arr[Mesh::ARRAY_VERTEX] = array; SceneTree *st = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()); debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, arr); if (st) { debug_mesh_cache->surface_set_material(0, st->get_debug_collision_material()); } } return debug_mesh_cache; }
Ref<Image> SimplexNoise::get_seamless_image(int p_size) { PoolVector<uint8_t> data; data.resize(p_size * p_size * 4); PoolVector<uint8_t>::Write wd8 = data.write(); for (int i = 0; i < p_size; i++) { for (int j = 0; j < p_size; j++) { float ii = (float)i / (float)p_size; float jj = (float)j / (float)p_size; ii *= 2.0 * Math_PI; jj *= 2.0 * Math_PI; float radius = p_size / (2.0 * Math_PI); float x = radius * Math::sin(jj); float y = radius * Math::cos(jj); float z = radius * Math::sin(ii); float w = radius * Math::cos(ii); float v = get_noise_4d(x, y, z, w); v = v * 0.5 + 0.5; // Normalize [0..1] uint8_t value = uint8_t(CLAMP(v * 255.0, 0, 255)); wd8[(i * p_size + j) * 4 + 0] = value; wd8[(i * p_size + j) * 4 + 1] = value; wd8[(i * p_size + j) * 4 + 2] = value; wd8[(i * p_size + j) * 4 + 3] = 255; } } Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_RGBA8, data)); return image; }
static PoolVector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) { ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), PoolVector<uint8_t>()); Ref<Image> img = p_image->duplicate(); if (img->detect_alpha()) img->convert(Image::FORMAT_RGBA8); else img->convert(Image::FORMAT_RGB8); Size2 s(img->get_width(), img->get_height()); PoolVector<uint8_t> data = img->get_data(); PoolVector<uint8_t>::Read r = data.read(); uint8_t *dst_buff = NULL; size_t dst_size = 0; if (img->get_format() == Image::FORMAT_RGB8) { dst_size = WebPEncodeRGB(r.ptr(), s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff); } else { dst_size = WebPEncodeRGBA(r.ptr(), s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff); } ERR_FAIL_COND_V(dst_size == 0, PoolVector<uint8_t>()); PoolVector<uint8_t> dst; dst.resize(4 + dst_size); PoolVector<uint8_t>::Write w = dst.write(); w[0] = 'W'; w[1] = 'E'; w[2] = 'B'; w[3] = 'P'; copymem(&w[4], dst_buff, dst_size); free(dst_buff); w = PoolVector<uint8_t>::Write(); return dst; }
PoolVector<Point2> Curve2D::bake(int p_subdivs) const { int pc = points.size(); PoolVector<Point2> ret; if (pc<2) return ret; ret.resize((pc-1)*p_subdivs+1); PoolVector<Point2>::Write w = ret.write(); const Point *r = points.ptr(); for(int i=0;i<pc;i++) { int ofs = pc*p_subdivs; int limit=(i==pc-1)?p_subdivs+1:p_subdivs; for(int j=0;j<limit;j++) { Vector2 p0 = r[i].pos; Vector2 p1 = p0+r[i].out; Vector2 p3 = r[i].pos; Vector2 p2 = p3+r[i].in; real_t t = j/(real_t)p_subdivs; w[ofs+j]=_bezier_interp(t,p0,p1,p2,p3); } } w = PoolVector<Point2>::Write(); return ret; }
RES ResourceFormatLoaderWAV::load(const String &p_path, const String& p_original_path, Error *r_error) { if (r_error) *r_error=ERR_FILE_CANT_OPEN; Error err; FileAccess *file=FileAccess::open(p_path, FileAccess::READ,&err); ERR_FAIL_COND_V( err!=OK, RES() ); if (r_error) *r_error=ERR_FILE_CORRUPT; /* CHECK RIFF */ char riff[5]; riff[4]=0; file->get_buffer((uint8_t*)&riff,4); //RIFF if (riff[0]!='R' || riff[1]!='I' || riff[2]!='F' || riff[3]!='F') { file->close(); memdelete(file); ERR_FAIL_V( RES() ); } /* GET FILESIZE */ uint32_t filesize=file->get_32(); /* CHECK WAVE */ char wave[4]; file->get_buffer((uint8_t*)&wave,4); //RIFF if (wave[0]!='W' || wave[1]!='A' || wave[2]!='V' || wave[3]!='E') { file->close(); memdelete(file); ERR_EXPLAIN("Not a WAV file (no WAVE RIFF Header)") ERR_FAIL_V( RES() ); } bool format_found=false; bool data_found=false; int format_bits=0; int format_channels=0; int format_freq=0; Sample::LoopFormat loop=Sample::LOOP_NONE; int loop_begin=0; int loop_end=0; Ref<Sample> sample( memnew( Sample ) ); while (!file->eof_reached()) { /* chunk */ char chunkID[4]; file->get_buffer((uint8_t*)&chunkID,4); //RIFF /* chunk size */ uint32_t chunksize=file->get_32(); uint32_t file_pos=file->get_position(); //save file pos, so we can skip to next chunk safely if (file->eof_reached()) { //ERR_PRINT("EOF REACH"); break; } if (chunkID[0]=='f' && chunkID[1]=='m' && chunkID[2]=='t' && chunkID[3]==' ' && !format_found) { /* IS FORMAT CHUNK */ uint16_t compression_code=file->get_16(); if (compression_code!=1) { ERR_PRINT("Format not supported for WAVE file (not PCM). Save WAVE files as uncompressed PCM instead."); break; } format_channels=file->get_16(); if (format_channels!=1 && format_channels !=2) { ERR_PRINT("Format not supported for WAVE file (not stereo or mono)"); break; } format_freq=file->get_32(); //sampling rate file->get_32(); // average bits/second (unused) file->get_16(); // block align (unused) format_bits=file->get_16(); // bits per sample if (format_bits%8) { ERR_PRINT("Strange number of bits in sample (not 8,16,24,32)"); break; } /* Don't need anything else, continue */ format_found=true; } if (chunkID[0]=='d' && chunkID[1]=='a' && chunkID[2]=='t' && chunkID[3]=='a' && !data_found) { /* IS FORMAT CHUNK */ data_found=true; if (!format_found) { ERR_PRINT("'data' chunk before 'format' chunk found."); break; } int frames=chunksize; frames/=format_channels; frames/=(format_bits>>3); /*print_line("chunksize: "+itos(chunksize)); print_line("channels: "+itos(format_channels)); print_line("bits: "+itos(format_bits)); */ sample->create( (format_bits==8) ? Sample::FORMAT_PCM8 : Sample::FORMAT_PCM16, (format_channels==2)?true:false, frames ); sample->set_mix_rate( format_freq ); int len=frames; if (format_channels==2) len*=2; if (format_bits>8) len*=2; PoolVector<uint8_t> data; data.resize(len); PoolVector<uint8_t>::Write dataw = data.write(); void * data_ptr = dataw.ptr(); for (int i=0;i<frames;i++) { for (int c=0;c<format_channels;c++) { if (format_bits==8) { // 8 bit samples are UNSIGNED uint8_t s = file->get_8(); s-=128; int8_t *sp=(int8_t*)&s; int8_t *data_ptr8=&((int8_t*)data_ptr)[i*format_channels+c]; *data_ptr8=*sp; } else { //16+ bits samples are SIGNED // if sample is > 16 bits, just read extra bytes uint32_t data=0; for (int b=0;b<(format_bits>>3);b++) { data|=((uint32_t)file->get_8())<<(b*8); } data<<=(32-format_bits); int32_t s=data; int16_t *data_ptr16=&((int16_t*)data_ptr)[i*format_channels+c]; *data_ptr16=s>>16; } } } dataw=PoolVector<uint8_t>::Write(); sample->set_data(data); if (file->eof_reached()) { file->close(); memdelete(file); ERR_EXPLAIN("Premature end of file."); ERR_FAIL_V(RES()); } } if (chunkID[0]=='s' && chunkID[1]=='m' && chunkID[2]=='p' && chunkID[3]=='l') { //loop point info! for(int i=0;i<10;i++) file->get_32(); // i wish to know why should i do this... no doc! loop=file->get_32()?Sample::LOOP_PING_PONG:Sample::LOOP_FORWARD; loop_begin=file->get_32(); loop_end=file->get_32(); } file->seek( file_pos+chunksize ); }
Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Ref<Image> p_image) { png_structp png; png_infop info; //png = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL); png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, _png_error_function, _png_warn_function, (png_voidp)NULL, _png_malloc_fn, _png_free_fn); ERR_FAIL_COND_V(!png, ERR_OUT_OF_MEMORY); info = png_create_info_struct(png); if (!info) { png_destroy_read_struct(&png, NULL, NULL); ERR_PRINT("Out of Memory"); return ERR_OUT_OF_MEMORY; } if (setjmp(png_jmpbuf(png))) { png_destroy_read_struct(&png, NULL, NULL); ERR_PRINT("PNG Corrupted"); return ERR_FILE_CORRUPT; } png_set_read_fn(png, (void *)rf_up, p_func); png_uint_32 width, height; int depth, color; png_read_info(png, info); png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL); //https://svn.gov.pt/projects/ccidadao/repository/middleware-offline/trunk/_src/eidmw/FreeImagePTEiD/Source/FreeImage/PluginPNG.cpp //png_get_text(png,info,) /* printf("Image width:%i\n", width); printf("Image Height:%i\n", height); printf("Bit depth:%i\n", depth); printf("Color type:%i\n", color); */ bool update_info = false; if (depth < 8) { //only bit dept 8 per channel is handled png_set_packing(png); update_info = true; }; if (png_get_color_type(png, info) == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png); update_info = true; } if (depth > 8) { png_set_strip_16(png); update_info = true; } if (png_get_valid(png, info, PNG_INFO_tRNS)) { //png_set_expand_gray_1_2_4_to_8(png); png_set_tRNS_to_alpha(png); update_info = true; } if (update_info) { png_read_update_info(png, info); png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL); } int components = 0; Image::Format fmt; switch (color) { case PNG_COLOR_TYPE_GRAY: { fmt = Image::FORMAT_L8; components = 1; } break; case PNG_COLOR_TYPE_GRAY_ALPHA: { fmt = Image::FORMAT_LA8; components = 2; } break; case PNG_COLOR_TYPE_RGB: { fmt = Image::FORMAT_RGB8; components = 3; } break; case PNG_COLOR_TYPE_RGB_ALPHA: { fmt = Image::FORMAT_RGBA8; components = 4; } break; default: { ERR_PRINT("INVALID PNG TYPE"); png_destroy_read_struct(&png, &info, NULL); return ERR_UNAVAILABLE; } break; } //int rowsize = png_get_rowbytes(png, info); int rowsize = components * width; PoolVector<uint8_t> dstbuff; dstbuff.resize(rowsize * height); PoolVector<uint8_t>::Write dstbuff_write = dstbuff.write(); uint8_t *data = dstbuff_write.ptr(); uint8_t **row_p = memnew_arr(uint8_t *, height); for (unsigned int i = 0; i < height; i++) { row_p[i] = &data[components * width * i]; } png_read_image(png, (png_bytep *)row_p); memdelete_arr(row_p); p_image->create(width, height, 0, fmt, dstbuff); png_destroy_read_struct(&png, &info, NULL); return OK; }
Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) { Ref<Sample> smp =p_from; ERR_FAIL_COND_V(smp.is_null(),Ref<Texture>()); int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); thumbnail_size*=EDSCALE; PoolVector<uint8_t> img; int w = thumbnail_size; int h = thumbnail_size; img.resize(w*h*3); PoolVector<uint8_t>::Write imgdata = img.write(); uint8_t * imgw = imgdata.ptr(); PoolVector<uint8_t> data = smp->get_data(); PoolVector<uint8_t>::Read sampledata = data.read(); const uint8_t *sdata=sampledata.ptr(); bool stereo = smp->is_stereo(); bool _16=smp->get_format()==Sample::FORMAT_PCM16; int len = smp->get_length(); if (len<1) return Ref<Texture>(); if (smp->get_format()==Sample::FORMAT_IMA_ADPCM) { struct IMA_ADPCM_State { int16_t step_index; int32_t predictor; /* values at loop point */ int16_t loop_step_index; int32_t loop_predictor; int32_t last_nibble; int32_t loop_pos; int32_t window_ofs; const uint8_t *ptr; } ima_adpcm; ima_adpcm.step_index=0; ima_adpcm.predictor=0; ima_adpcm.loop_step_index=0; ima_adpcm.loop_predictor=0; ima_adpcm.last_nibble=-1; ima_adpcm.loop_pos=0x7FFFFFFF; ima_adpcm.window_ofs=0; ima_adpcm.ptr=NULL; for(int i=0;i<w;i++) { float max[2]={-1e10,-1e10}; float min[2]={1e10,1e10}; int from = i*len/w; int to = (i+1)*len/w; if (to>=len) to=len-1; for(int j=from;j<to;j++) { while(j>ima_adpcm.last_nibble) { static const int16_t _ima_adpcm_step_table[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; static const int8_t _ima_adpcm_index_table[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 }; int16_t nibble,diff,step; ima_adpcm.last_nibble++; const uint8_t *src_ptr=sdata; int ofs = ima_adpcm.last_nibble>>1; if (stereo) ofs*=2; nibble = (ima_adpcm.last_nibble&1)? (src_ptr[ofs]>>4):(src_ptr[ofs]&0xF); step=_ima_adpcm_step_table[ima_adpcm.step_index]; ima_adpcm.step_index += _ima_adpcm_index_table[nibble]; if (ima_adpcm.step_index<0) ima_adpcm.step_index=0; if (ima_adpcm.step_index>88) ima_adpcm.step_index=88; diff = step >> 3 ; if (nibble & 1) diff += step >> 2 ; if (nibble & 2) diff += step >> 1 ; if (nibble & 4) diff += step ; if (nibble & 8) diff = -diff ; ima_adpcm.predictor+=diff; if (ima_adpcm.predictor<-0x8000) ima_adpcm.predictor=-0x8000; else if (ima_adpcm.predictor>0x7FFF) ima_adpcm.predictor=0x7FFF; /* store loop if there */ if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) { ima_adpcm.loop_step_index = ima_adpcm.step_index; ima_adpcm.loop_predictor = ima_adpcm.predictor; } } float v=ima_adpcm.predictor/32767.0; if (v>max[0]) max[0]=v; if (v<min[0]) min[0]=v; } max[0]*=0.8; min[0]*=0.8; for(int j=0;j<h;j++) { float v = (j/(float)h) * 2.0 - 1.0; uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; if (v>min[0] && v<max[0]) { imgofs[0]=255; imgofs[1]=150; imgofs[2]=80; } else { imgofs[0]=0; imgofs[1]=0; imgofs[2]=0; } } } } else { for(int i=0;i<w;i++) {
Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES& p_from) { Ref<BitMap> bm =p_from; if (bm->get_size()==Size2()) { return Ref<Texture>(); } PoolVector<uint8_t> data; data.resize(bm->get_size().width*bm->get_size().height); { PoolVector<uint8_t>::Write w=data.write(); for(int i=0;i<bm->get_size().width;i++) { for(int j=0;j<bm->get_size().height;j++) { if (bm->get_bit(Point2i(i,j))) { w[j*bm->get_size().width+i]=255; } else { w[j*bm->get_size().width+i]=0; } } } } Image img(bm->get_size().width,bm->get_size().height,0,Image::FORMAT_L8,data); int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); thumbnail_size*=EDSCALE; if (img.is_compressed()) { if (img.decompress()!=OK) return Ref<Texture>(); } else if (img.get_format()!=Image::FORMAT_RGB8 && img.get_format()!=Image::FORMAT_RGBA8) { img.convert(Image::FORMAT_RGBA8); } int width,height; if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) { width=thumbnail_size; height = img.get_height() * thumbnail_size / img.get_width(); } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) { height=thumbnail_size; width = img.get_width() * thumbnail_size / img.get_height(); } else { width=img.get_width(); height=img.get_height(); } img.resize(width,height); Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); ptex->create_from_image(img,0); return ptex; }
void ProceduralSky::_update_sky() { update_queued = false; PoolVector<uint8_t> imgdata; static const int size[TEXTURE_SIZE_MAX] = { 1024, 2048, 4096 }; int w = size[texture_size]; int h = w / 2; imgdata.resize(w * h * 4); //RGBE { PoolVector<uint8_t>::Write dataw = imgdata.write(); uint32_t *ptr = (uint32_t *)dataw.ptr(); Color sky_top_linear = sky_top_color.to_linear(); Color sky_horizon_linear = sky_horizon_color.to_linear(); Color ground_bottom_linear = ground_bottom_color.to_linear(); Color ground_horizon_linear = ground_horizon_color.to_linear(); //Color sun_linear = sun_color.to_linear(); Vector3 sun(0, 0, -1); sun = Basis(Vector3(1, 0, 0), Math::deg2rad(sun_latitude)).xform(sun); sun = Basis(Vector3(0, 1, 0), Math::deg2rad(sun_longitude)).xform(sun); sun.normalize(); for (int i = 0; i < w; i++) { float u = float(i) / (w - 1); float phi = u * 2.0 * Math_PI; for (int j = 0; j < h; j++) { float v = float(j) / (h - 1); float theta = v * Math_PI; Vector3 normal( Math::sin(phi) * Math::sin(theta) * -1.0, Math::cos(theta), Math::cos(phi) * Math::sin(theta) * -1.0); normal.normalize(); float v_angle = Math::acos(normal.y); Color color; if (normal.y < 0) { //ground float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5); color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve)); } else { float c = v_angle / (Math_PI * 0.5); color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve)); float sun_angle = Math::rad2deg(Math::acos(sun.dot(normal))); if (sun_angle < sun_angle_min) { color = color.blend(sun_color); } else if (sun_angle < sun_angle_max) { float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min); c2 = Math::ease(c2, sun_curve); color = color.blend(sun_color).linear_interpolate(color, c2); } } ptr[j * w + i] = color.to_rgbe9995(); } } } Ref<Image> image; image.instance(); image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata); VS::get_singleton()->texture_allocate(texture, w, h, Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); VS::get_singleton()->texture_set_data(texture, image); _radiance_changed(); }
Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { uint32_t type = f->get_32(); print_bl("find property of type: " + itos(type)); switch (type) { case VARIANT_NIL: { r_v = Variant(); } break; case VARIANT_BOOL: { r_v = bool(f->get_32()); } break; case VARIANT_INT: { r_v = int(f->get_32()); } break; case VARIANT_INT64: { r_v = int64_t(f->get_64()); } break; case VARIANT_REAL: { r_v = f->get_real(); } break; case VARIANT_DOUBLE: { r_v = f->get_double(); } break; case VARIANT_STRING: { r_v = get_unicode_string(); } break; case VARIANT_VECTOR2: { Vector2 v; v.x = f->get_real(); v.y = f->get_real(); r_v = v; } break; case VARIANT_RECT2: { Rect2 v; v.position.x = f->get_real(); v.position.y = f->get_real(); v.size.x = f->get_real(); v.size.y = f->get_real(); r_v = v; } break; case VARIANT_VECTOR3: { Vector3 v; v.x = f->get_real(); v.y = f->get_real(); v.z = f->get_real(); r_v = v; } break; case VARIANT_PLANE: { Plane v; v.normal.x = f->get_real(); v.normal.y = f->get_real(); v.normal.z = f->get_real(); v.d = f->get_real(); r_v = v; } break; case VARIANT_QUAT: { Quat v; v.x = f->get_real(); v.y = f->get_real(); v.z = f->get_real(); v.w = f->get_real(); r_v = v; } break; case VARIANT_AABB: { AABB v; v.position.x = f->get_real(); v.position.y = f->get_real(); v.position.z = f->get_real(); v.size.x = f->get_real(); v.size.y = f->get_real(); v.size.z = f->get_real(); r_v = v; } break; case VARIANT_MATRIX32: { Transform2D v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); v.elements[1].x = f->get_real(); v.elements[1].y = f->get_real(); v.elements[2].x = f->get_real(); v.elements[2].y = f->get_real(); r_v = v; } break; case VARIANT_MATRIX3: { Basis v; v.elements[0].x = f->get_real(); v.elements[0].y = f->get_real(); v.elements[0].z = f->get_real(); v.elements[1].x = f->get_real(); v.elements[1].y = f->get_real(); v.elements[1].z = f->get_real(); v.elements[2].x = f->get_real(); v.elements[2].y = f->get_real(); v.elements[2].z = f->get_real(); r_v = v; } break; case VARIANT_TRANSFORM: { Transform v; v.basis.elements[0].x = f->get_real(); v.basis.elements[0].y = f->get_real(); v.basis.elements[0].z = f->get_real(); v.basis.elements[1].x = f->get_real(); v.basis.elements[1].y = f->get_real(); v.basis.elements[1].z = f->get_real(); v.basis.elements[2].x = f->get_real(); v.basis.elements[2].y = f->get_real(); v.basis.elements[2].z = f->get_real(); v.origin.x = f->get_real(); v.origin.y = f->get_real(); v.origin.z = f->get_real(); r_v = v; } break; case VARIANT_COLOR: { Color v; v.r = f->get_real(); v.g = f->get_real(); v.b = f->get_real(); v.a = f->get_real(); r_v = v; } break; case VARIANT_NODE_PATH: { Vector<StringName> names; Vector<StringName> subnames; bool absolute; int name_count = f->get_16(); uint32_t subname_count = f->get_16(); absolute = subname_count & 0x8000; subname_count &= 0x7FFF; if (ver_format < FORMAT_VERSION_NO_NODEPATH_PROPERTY) { subname_count += 1; // has a property field, so we should count it as well } for (int i = 0; i < name_count; i++) names.push_back(_get_string()); for (uint32_t i = 0; i < subname_count; i++) subnames.push_back(_get_string()); NodePath np = NodePath(names, subnames, absolute); r_v = np; } break; case VARIANT_RID: { r_v = f->get_32(); } break; case VARIANT_OBJECT: { uint32_t objtype = f->get_32(); switch (objtype) { case OBJECT_EMPTY: { //do none } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index = f->get_32(); String path = res_path + "::" + itos(index); RES res = ResourceLoader::load(path); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); } r_v = res; } break; case OBJECT_EXTERNAL_RESOURCE: { //old file format, still around for compatibility String exttype = get_unicode_string(); String path = get_unicode_string(); if (path.find("://") == -1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path)); } if (remaps.find(path)) { path = remaps[path]; } RES res = ResourceLoader::load(path, exttype); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); } r_v = res; } break; case OBJECT_EXTERNAL_RESOURCE_INDEX: { //new file format, just refers to an index in the external list int erindex = f->get_32(); if (erindex < 0 || erindex >= external_resources.size()) { WARN_PRINT("Broken external resource! (index out of size)"); r_v = Variant(); } else { String exttype = external_resources[erindex].type; String path = external_resources[erindex].path; if (path.find("://") == -1 && path.is_rel_path()) { // path is relative to file being loaded, so convert to a resource path path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path)); } RES res = ResourceLoader::load(path, exttype); if (res.is_null()) { WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); } r_v = res; } } break; default: { ERR_FAIL_V(ERR_FILE_CORRUPT); } break; } } break; case VARIANT_DICTIONARY: { uint32_t len = f->get_32(); Dictionary d; //last bit means shared len &= 0x7FFFFFFF; for (uint32_t i = 0; i < len; i++) { Variant key; Error err = parse_variant(key); ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT); Variant value; err = parse_variant(value); ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT); d[key] = value; } r_v = d; } break; case VARIANT_ARRAY: { uint32_t len = f->get_32(); Array a; //last bit means shared len &= 0x7FFFFFFF; a.resize(len); for (uint32_t i = 0; i < len; i++) { Variant val; Error err = parse_variant(val); ERR_FAIL_COND_V(err, ERR_FILE_CORRUPT); a[i] = val; } r_v = a; } break; case VARIANT_RAW_ARRAY: { uint32_t len = f->get_32(); PoolVector<uint8_t> array; array.resize(len); PoolVector<uint8_t>::Write w = array.write(); f->get_buffer(w.ptr(), len); _advance_padding(len); w = PoolVector<uint8_t>::Write(); r_v = array; } break; case VARIANT_INT_ARRAY: { uint32_t len = f->get_32(); PoolVector<int> array; array.resize(len); PoolVector<int>::Write w = array.write(); f->get_buffer((uint8_t *)w.ptr(), len * 4); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr = (uint32_t *)w.ptr(); for (int i = 0; i < len; i++) { ptr[i] = BSWAP32(ptr[i]); } } #endif w = PoolVector<int>::Write(); r_v = array; } break; case VARIANT_REAL_ARRAY: { uint32_t len = f->get_32(); PoolVector<real_t> array; array.resize(len); PoolVector<real_t>::Write w = array.write(); f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t)); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr = (uint32_t *)w.ptr(); for (int i = 0; i < len; i++) { ptr[i] = BSWAP32(ptr[i]); } } #endif w = PoolVector<real_t>::Write(); r_v = array; } break; case VARIANT_STRING_ARRAY: { uint32_t len = f->get_32(); PoolVector<String> array; array.resize(len); PoolVector<String>::Write w = array.write(); for (uint32_t i = 0; i < len; i++) w[i] = get_unicode_string(); w = PoolVector<String>::Write(); r_v = array; } break; case VARIANT_VECTOR2_ARRAY: { uint32_t len = f->get_32(); PoolVector<Vector2> array; array.resize(len); PoolVector<Vector2>::Write w = array.write(); if (sizeof(Vector2) == 8) { f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 2); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr = (uint32_t *)w.ptr(); for (int i = 0; i < len * 2; i++) { ptr[i] = BSWAP32(ptr[i]); } } #endif } else { ERR_EXPLAIN("Vector2 size is NOT 8!"); ERR_FAIL_V(ERR_UNAVAILABLE); } w = PoolVector<Vector2>::Write(); r_v = array; } break; case VARIANT_VECTOR3_ARRAY: { uint32_t len = f->get_32(); PoolVector<Vector3> array; array.resize(len); PoolVector<Vector3>::Write w = array.write(); if (sizeof(Vector3) == 12) { f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 3); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr = (uint32_t *)w.ptr(); for (int i = 0; i < len * 3; i++) { ptr[i] = BSWAP32(ptr[i]); } } #endif } else { ERR_EXPLAIN("Vector3 size is NOT 12!"); ERR_FAIL_V(ERR_UNAVAILABLE); } w = PoolVector<Vector3>::Write(); r_v = array; } break; case VARIANT_COLOR_ARRAY: { uint32_t len = f->get_32(); PoolVector<Color> array; array.resize(len); PoolVector<Color>::Write w = array.write(); if (sizeof(Color) == 16) { f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 4); #ifdef BIG_ENDIAN_ENABLED { uint32_t *ptr = (uint32_t *)w.ptr(); for (int i = 0; i < len * 4; i++) { ptr[i] = BSWAP32(ptr[i]); } } #endif } else { ERR_EXPLAIN("Color size is NOT 16!"); ERR_FAIL_V(ERR_UNAVAILABLE); } w = PoolVector<Color>::Write(); r_v = array; } break; #ifndef DISABLE_DEPRECATED case VARIANT_IMAGE: { uint32_t encoding = f->get_32(); if (encoding == IMAGE_ENCODING_EMPTY) { r_v = Ref<Image>(); break; } else if (encoding == IMAGE_ENCODING_RAW) { uint32_t width = f->get_32(); uint32_t height = f->get_32(); uint32_t mipmaps = f->get_32(); uint32_t format = f->get_32(); const uint32_t format_version_shift = 24; const uint32_t format_version_mask = format_version_shift - 1; uint32_t format_version = format >> format_version_shift; const uint32_t current_version = 0; if (format_version > current_version) { ERR_PRINT("Format version for encoded binary image is too new"); return ERR_PARSE_ERROR; } Image::Format fmt = Image::Format(format & format_version_mask); //if format changes, we can add a compatibility bit on top uint32_t datalen = f->get_32(); PoolVector<uint8_t> imgdata; imgdata.resize(datalen); PoolVector<uint8_t>::Write w = imgdata.write(); f->get_buffer(w.ptr(), datalen); _advance_padding(datalen); w = PoolVector<uint8_t>::Write(); Ref<Image> image; image.instance(); image->create(width, height, mipmaps, fmt, imgdata); r_v = image; } else { //compressed PoolVector<uint8_t> data; data.resize(f->get_32()); PoolVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(), data.size()); w = PoolVector<uint8_t>::Write(); Ref<Image> image; if (encoding == IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) { image = Image::lossy_unpacker(data); } else if (encoding == IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) { image = Image::lossless_unpacker(data); } _advance_padding(data.size()); r_v = image; } } break;