Added ability for multiple images to be imported as an atlas
This adds support for groups in the import system, which point to a single file. Add property hint for saving files in file field
This commit is contained in:
parent
8e652a1400
commit
04847ef5f9
35 changed files with 1818 additions and 33 deletions
|
@ -1876,7 +1876,7 @@ Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const P
|
||||||
|
|
||||||
Rect2 Image::get_used_rect() const {
|
Rect2 Image::get_used_rect() const {
|
||||||
|
|
||||||
if (format != FORMAT_LA8 && format != FORMAT_RGBA8)
|
if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGBA5551)
|
||||||
return Rect2(Point2(), Size2(width, height));
|
return Rect2(Point2(), Size2(width, height));
|
||||||
|
|
||||||
int len = data.size();
|
int len = data.size();
|
||||||
|
@ -1884,17 +1884,13 @@ Rect2 Image::get_used_rect() const {
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return Rect2();
|
return Rect2();
|
||||||
|
|
||||||
//int data_size = len;
|
const_cast<Image *>(this)->lock();
|
||||||
PoolVector<uint8_t>::Read r = data.read();
|
|
||||||
const unsigned char *rptr = r.ptr();
|
|
||||||
|
|
||||||
int ps = format == FORMAT_LA8 ? 2 : 4;
|
|
||||||
int minx = 0xFFFFFF, miny = 0xFFFFFFF;
|
int minx = 0xFFFFFF, miny = 0xFFFFFFF;
|
||||||
int maxx = -1, maxy = -1;
|
int maxx = -1, maxy = -1;
|
||||||
for (int j = 0; j < height; j++) {
|
for (int j = 0; j < height; j++) {
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
|
|
||||||
bool opaque = rptr[(j * width + i) * ps + (ps - 1)] > 2;
|
bool opaque = get_pixel(i, j).a > 0.99;
|
||||||
if (!opaque)
|
if (!opaque)
|
||||||
continue;
|
continue;
|
||||||
if (i > maxx)
|
if (i > maxx)
|
||||||
|
@ -1908,6 +1904,8 @@ Rect2 Image::get_used_rect() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const_cast<Image *>(this)->unlock();
|
||||||
|
|
||||||
if (maxx == -1)
|
if (maxx == -1)
|
||||||
return Rect2();
|
return Rect2();
|
||||||
else
|
else
|
||||||
|
|
|
@ -94,6 +94,8 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
|
||||||
r_path_and_type.type = value;
|
r_path_and_type.type = value;
|
||||||
} else if (assign == "importer") {
|
} else if (assign == "importer") {
|
||||||
r_path_and_type.importer = value;
|
r_path_and_type.importer = value;
|
||||||
|
} else if (assign == "group_file") {
|
||||||
|
r_path_and_type.group_file = value;
|
||||||
} else if (assign == "metadata") {
|
} else if (assign == "metadata") {
|
||||||
r_path_and_type.metadata = value;
|
r_path_and_type.metadata = value;
|
||||||
} else if (assign == "valid") {
|
} else if (assign == "valid") {
|
||||||
|
@ -294,6 +296,15 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
|
||||||
memdelete(f);
|
memdelete(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ResourceFormatImporter::get_import_group_file(const String &p_path) const {
|
||||||
|
|
||||||
|
bool valid = true;
|
||||||
|
PathAndType pat;
|
||||||
|
_get_path_and_type(p_path, pat, &valid);
|
||||||
|
return valid?pat.group_file:String();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
|
bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
|
||||||
|
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
|
|
|
@ -43,6 +43,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
|
||||||
String path;
|
String path;
|
||||||
String type;
|
String type;
|
||||||
String importer;
|
String importer;
|
||||||
|
String group_file;
|
||||||
Variant metadata;
|
Variant metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,6 +70,7 @@ public:
|
||||||
virtual bool is_import_valid(const String &p_path) const;
|
virtual bool is_import_valid(const String &p_path) const;
|
||||||
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
||||||
virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); }
|
virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); }
|
||||||
|
virtual String get_import_group_file(const String &p_path) const;
|
||||||
virtual bool exists(const String &p_path) const;
|
virtual bool exists(const String &p_path) const;
|
||||||
|
|
||||||
virtual bool can_be_imported(const String &p_path) const;
|
virtual bool can_be_imported(const String &p_path) const;
|
||||||
|
@ -120,8 +122,11 @@ public:
|
||||||
|
|
||||||
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const = 0;
|
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const = 0;
|
||||||
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const = 0;
|
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const = 0;
|
||||||
|
virtual String get_option_group_file() const { return String(); }
|
||||||
|
|
||||||
virtual Error 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 = NULL, Variant *r_metadata = NULL) = 0;
|
virtual Error 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 = NULL, Variant *r_metadata = NULL) = 0;
|
||||||
|
|
||||||
|
virtual Error import_group_file(const String& p_group_file,const Map<String,Map<StringName, Variant> >&p_source_file_options, const Map<String,String>& p_base_paths) { return ERR_UNAVAILABLE; }
|
||||||
virtual bool are_import_settings_valid(const String &p_path) const { return true; }
|
virtual bool are_import_settings_valid(const String &p_path) const { return true; }
|
||||||
virtual String get_import_settings_string() const { return String(); }
|
virtual String get_import_settings_string() const { return String(); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -608,6 +608,30 @@ int ResourceLoader::get_import_order(const String &p_path) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String ResourceLoader::get_import_group_file(const String &p_path) {
|
||||||
|
String path = _path_remap(p_path);
|
||||||
|
|
||||||
|
String local_path;
|
||||||
|
if (path.is_rel_path())
|
||||||
|
local_path = "res://" + path;
|
||||||
|
else
|
||||||
|
local_path = ProjectSettings::get_singleton()->localize_path(path);
|
||||||
|
|
||||||
|
for (int i = 0; i < loader_count; i++) {
|
||||||
|
|
||||||
|
if (!loader[i]->recognize_path(local_path))
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
|
||||||
|
continue;
|
||||||
|
*/
|
||||||
|
|
||||||
|
return loader[i]->get_import_group_file(p_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(); //not found
|
||||||
|
}
|
||||||
|
|
||||||
bool ResourceLoader::is_import_valid(const String &p_path) {
|
bool ResourceLoader::is_import_valid(const String &p_path) {
|
||||||
|
|
||||||
String path = _path_remap(p_path);
|
String path = _path_remap(p_path);
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
virtual bool is_import_valid(const String &p_path) const { return true; }
|
virtual bool is_import_valid(const String &p_path) const { return true; }
|
||||||
virtual bool is_imported(const String &p_path) const { return false; }
|
virtual bool is_imported(const String &p_path) const { return false; }
|
||||||
virtual int get_import_order(const String &p_path) const { return 0; }
|
virtual int get_import_order(const String &p_path) const { return 0; }
|
||||||
|
virtual String get_import_group_file(const String &p_path) const { return ""; } //no group
|
||||||
|
|
||||||
virtual ~ResourceFormatLoader() {}
|
virtual ~ResourceFormatLoader() {}
|
||||||
};
|
};
|
||||||
|
@ -155,6 +156,7 @@ public:
|
||||||
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
|
||||||
static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
|
static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
|
||||||
static bool is_import_valid(const String &p_path);
|
static bool is_import_valid(const String &p_path);
|
||||||
|
static String get_import_group_file(const String &p_path);
|
||||||
static bool is_imported(const String &p_path);
|
static bool is_imported(const String &p_path);
|
||||||
static int get_import_order(const String &p_path);
|
static int get_import_order(const String &p_path);
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ Size2 Transform2D::get_scale() const {
|
||||||
return Size2(elements[0].length(), det_sign * elements[1].length());
|
return Size2(elements[0].length(), det_sign * elements[1].length());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform2D::set_scale(Size2 &p_scale) {
|
void Transform2D::set_scale(const Size2 &p_scale) {
|
||||||
elements[0].normalize();
|
elements[0].normalize();
|
||||||
elements[1].normalize();
|
elements[1].normalize();
|
||||||
elements[0] *= p_scale.x;
|
elements[0] *= p_scale.x;
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct Transform2D {
|
||||||
real_t basis_determinant() const;
|
real_t basis_determinant() const;
|
||||||
|
|
||||||
Size2 get_scale() const;
|
Size2 get_scale() const;
|
||||||
void set_scale(Size2 &p_scale);
|
void set_scale(const Size2 &p_scale);
|
||||||
|
|
||||||
_FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; }
|
_FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; }
|
||||||
_FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; }
|
_FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; }
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct Vector2 {
|
||||||
Vector2 operator/(const real_t &rvalue) const;
|
Vector2 operator/(const real_t &rvalue) const;
|
||||||
|
|
||||||
void operator/=(const real_t &rvalue);
|
void operator/=(const real_t &rvalue);
|
||||||
|
void operator/=(const Vector2 &rvalue) { *this = *this / rvalue; }
|
||||||
|
|
||||||
Vector2 operator-() const;
|
Vector2 operator-() const;
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ enum PropertyHint {
|
||||||
PROPERTY_HINT_PROPERTY_OF_SCRIPT, ///< a property of a script & base
|
PROPERTY_HINT_PROPERTY_OF_SCRIPT, ///< a property of a script & base
|
||||||
PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send
|
PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send
|
||||||
PROPERTY_HINT_NODE_PATH_VALID_TYPES,
|
PROPERTY_HINT_NODE_PATH_VALID_TYPES,
|
||||||
|
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
|
||||||
PROPERTY_HINT_MAX,
|
PROPERTY_HINT_MAX,
|
||||||
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
|
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
|
||||||
};
|
};
|
||||||
|
|
|
@ -197,6 +197,19 @@ public:
|
||||||
r.reference = NULL;
|
r.reference = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T_Other>
|
||||||
|
void reference_ptr(T_Other *p_ptr) {
|
||||||
|
if (reference == p_ptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unref();
|
||||||
|
|
||||||
|
T *r = Object::cast_to<T>(p_ptr);
|
||||||
|
if (r) {
|
||||||
|
ref_pointer(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ref(const Ref &p_from) {
|
Ref(const Ref &p_from) {
|
||||||
|
|
||||||
reference = NULL;
|
reference = NULL;
|
||||||
|
|
|
@ -826,6 +826,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform * mesh->transform);
|
||||||
|
|
||||||
RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.getornull(mesh->mesh);
|
RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.getornull(mesh->mesh);
|
||||||
if (mesh_data) {
|
if (mesh_data) {
|
||||||
|
|
||||||
|
@ -834,7 +836,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
// materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
|
// materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
|
||||||
glBindVertexArray(s->array_id);
|
glBindVertexArray(s->array_id);
|
||||||
|
|
||||||
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
|
glVertexAttrib4f(VS::ARRAY_COLOR, mesh->modulate.r, mesh->modulate.g, mesh->modulate.b, mesh->modulate.a);
|
||||||
|
|
||||||
if (s->index_array_len) {
|
if (s->index_array_len) {
|
||||||
glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
|
glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
|
||||||
|
@ -845,6 +847,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Item::Command::TYPE_MULTIMESH: {
|
case Item::Command::TYPE_MULTIMESH: {
|
||||||
|
|
||||||
|
|
265
editor/editor_atlas_packer.cpp
Normal file
265
editor/editor_atlas_packer.cpp
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
#include "editor_atlas_packer.h"
|
||||||
|
|
||||||
|
void EditorAtlasPacker::_plot_triangle(Ref<BitMap> p_bitmap, Vector2i *vertices) {
|
||||||
|
|
||||||
|
int width = p_bitmap->get_size().width;
|
||||||
|
int height = p_bitmap->get_size().height;
|
||||||
|
int x[3];
|
||||||
|
int y[3];
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
|
||||||
|
x[j] = vertices[j].x;
|
||||||
|
y[j] = vertices[j].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the points vertically
|
||||||
|
if (y[1] > y[2]) {
|
||||||
|
SWAP(x[1], x[2]);
|
||||||
|
SWAP(y[1], y[2]);
|
||||||
|
}
|
||||||
|
if (y[0] > y[1]) {
|
||||||
|
SWAP(x[0], x[1]);
|
||||||
|
SWAP(y[0], y[1]);
|
||||||
|
}
|
||||||
|
if (y[1] > y[2]) {
|
||||||
|
SWAP(x[1], x[2]);
|
||||||
|
SWAP(y[1], y[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
double dx_far = double(x[2] - x[0]) / (y[2] - y[0] + 1);
|
||||||
|
double dx_upper = double(x[1] - x[0]) / (y[1] - y[0] + 1);
|
||||||
|
double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1);
|
||||||
|
double xf = x[0];
|
||||||
|
double xt = x[0] + dx_upper; // if y[0] == y[1], special case
|
||||||
|
for (int yi = y[0]; yi <= (y[2] > height - 1 ? height - 1 : y[2]); yi++) {
|
||||||
|
if (yi >= 0) {
|
||||||
|
for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) {
|
||||||
|
//pixels[int(x + y * width)] = color;
|
||||||
|
|
||||||
|
p_bitmap->set_bit(Point2(xi, yi), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
|
||||||
|
|
||||||
|
p_bitmap->set_bit(Point2(xi, yi), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xf += dx_far;
|
||||||
|
if (yi < y[1])
|
||||||
|
xt += dx_upper;
|
||||||
|
else
|
||||||
|
xt += dx_low;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_height, int p_atlas_max_size, int p_cell_resolution) {
|
||||||
|
|
||||||
|
int divide_by = MIN(64, p_cell_resolution);
|
||||||
|
Vector<PlottedBitmap> bitmaps;
|
||||||
|
|
||||||
|
int max_w = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < charts.size(); i++) {
|
||||||
|
|
||||||
|
const Chart &chart = charts[i];
|
||||||
|
|
||||||
|
//generate aabb
|
||||||
|
|
||||||
|
Rect2i aabb;
|
||||||
|
int vertex_count = chart.vertices.size();
|
||||||
|
const Vector2 *vertices = chart.vertices.ptr();
|
||||||
|
|
||||||
|
for (int j = 0; j < vertex_count; j++) {
|
||||||
|
|
||||||
|
if (j == 0) {
|
||||||
|
aabb.position = vertices[j];
|
||||||
|
} else {
|
||||||
|
aabb.expand_to(vertices[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<BitMap> src_bitmap;
|
||||||
|
src_bitmap.instance();
|
||||||
|
src_bitmap->create(aabb.size / divide_by);
|
||||||
|
|
||||||
|
int w = src_bitmap->get_size().width;
|
||||||
|
int h = src_bitmap->get_size().height;
|
||||||
|
|
||||||
|
//plot triangles, using divisor
|
||||||
|
|
||||||
|
for (int j = 0; j < chart.faces.size(); j++) {
|
||||||
|
|
||||||
|
Vector2i v[3];
|
||||||
|
for (int k = 0; k < 3; k++) {
|
||||||
|
Vector2 vtx = chart.vertices[chart.faces[j].vertex[k]];
|
||||||
|
vtx -= aabb.position;
|
||||||
|
vtx /= divide_by;
|
||||||
|
v[k] = vtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
_plot_triangle(src_bitmap, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
//src_bitmap->convert_to_image()->save_png("bitmap" + itos(i) + ".png");
|
||||||
|
|
||||||
|
//grow by 1 for each side
|
||||||
|
|
||||||
|
int bmw = src_bitmap->get_size().width + 2;
|
||||||
|
int bmh = src_bitmap->get_size().height + 2;
|
||||||
|
|
||||||
|
int heights_size = -1;
|
||||||
|
bool transpose = false;
|
||||||
|
if (chart.can_transpose && bmh > bmw) {
|
||||||
|
heights_size = bmh;
|
||||||
|
transpose = true;
|
||||||
|
} else {
|
||||||
|
heights_size = bmw;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_w = MAX(max_w, heights_size);
|
||||||
|
|
||||||
|
Vector<int> top_heights;
|
||||||
|
Vector<int> bottom_heights;
|
||||||
|
top_heights.resize(heights_size);
|
||||||
|
bottom_heights.resize(heights_size);
|
||||||
|
|
||||||
|
for (int x = 0; x < heights_size; x++) {
|
||||||
|
top_heights.write[x] = -1;
|
||||||
|
bottom_heights.write[x] = 0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < bmw; x++) {
|
||||||
|
for (int y = 0; y < bmh; y++) {
|
||||||
|
bool found_pixel = false;
|
||||||
|
for (int lx = x - 1; lx < x + 2 && !found_pixel; lx++) {
|
||||||
|
for (int ly = y - 1; ly < y + 2 && !found_pixel; ly++) {
|
||||||
|
|
||||||
|
int px = lx - 1;
|
||||||
|
if (px < 0 || px >= w)
|
||||||
|
continue;
|
||||||
|
int py = ly - 1;
|
||||||
|
if (py < 0 || py >= h)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (src_bitmap->get_bit(Vector2(px, py))) {
|
||||||
|
found_pixel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found_pixel) {
|
||||||
|
|
||||||
|
if (transpose) {
|
||||||
|
if (x > top_heights[y]) {
|
||||||
|
top_heights.write[y] = x;
|
||||||
|
}
|
||||||
|
if (x < bottom_heights[y]) {
|
||||||
|
bottom_heights.write[y] = x;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (y > top_heights[x]) {
|
||||||
|
top_heights.write[x] = y;
|
||||||
|
}
|
||||||
|
if (y < bottom_heights[x]) {
|
||||||
|
bottom_heights.write[x] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String row;
|
||||||
|
for (int j = 0; j < top_heights.size(); j++) {
|
||||||
|
row += "(" + itos(top_heights[j]) + "-" + itos(bottom_heights[j]) + "),";
|
||||||
|
}
|
||||||
|
|
||||||
|
PlottedBitmap plotted_bitmap;
|
||||||
|
plotted_bitmap.offset = aabb.position;
|
||||||
|
plotted_bitmap.top_heights = top_heights;
|
||||||
|
plotted_bitmap.bottom_heights = bottom_heights;
|
||||||
|
plotted_bitmap.chart_index = i;
|
||||||
|
plotted_bitmap.transposed = transpose;
|
||||||
|
plotted_bitmap.area = bmw * bmh;
|
||||||
|
|
||||||
|
bitmaps.push_back(plotted_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmaps.sort();
|
||||||
|
|
||||||
|
int atlas_max_width = nearest_power_of_2_templated(p_atlas_max_size) / divide_by;
|
||||||
|
int atlas_w = nearest_power_of_2_templated(max_w);
|
||||||
|
int atlas_h;
|
||||||
|
while (true) {
|
||||||
|
atlas_h = 0;
|
||||||
|
|
||||||
|
//do a tetris
|
||||||
|
Vector<int> heights;
|
||||||
|
heights.resize(atlas_w);
|
||||||
|
for (int i = 0; i < atlas_w; i++) {
|
||||||
|
heights.write[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *atlas_ptr = heights.ptrw();
|
||||||
|
|
||||||
|
for (int i = 0; i < bitmaps.size(); i++) {
|
||||||
|
|
||||||
|
int best_height = 0x7FFFFFFF;
|
||||||
|
int best_height_offset = -1;
|
||||||
|
int w = bitmaps[i].top_heights.size();
|
||||||
|
|
||||||
|
const int *top_heights = bitmaps[i].top_heights.ptr();
|
||||||
|
const int *bottom_heights = bitmaps[i].bottom_heights.ptr();
|
||||||
|
|
||||||
|
for (int j = 0; j < atlas_w - w; j++) {
|
||||||
|
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
|
for (int k = 0; k < w; k++) {
|
||||||
|
|
||||||
|
int pixmap_h = bottom_heights[k];
|
||||||
|
if (pixmap_h == -1) {
|
||||||
|
continue; //no pixel here, anything is fine
|
||||||
|
}
|
||||||
|
|
||||||
|
int h = MAX(0, atlas_ptr[j + k] - pixmap_h);
|
||||||
|
if (h > height) {
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height < best_height) {
|
||||||
|
best_height = height;
|
||||||
|
best_height_offset = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < w; j++) { //add
|
||||||
|
if (top_heights[j] == -1) { //unused
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int height = best_height + top_heights[j] + 1;
|
||||||
|
atlas_ptr[j + best_height_offset] = height;
|
||||||
|
atlas_h = MAX(atlas_h, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set
|
||||||
|
Vector2 offset = bitmaps[i].offset;
|
||||||
|
if (bitmaps[i].transposed) {
|
||||||
|
SWAP(offset.x, offset.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 final_pos = Vector2(best_height_offset * divide_by, best_height * divide_by) + Vector2(divide_by, divide_by) - offset;
|
||||||
|
charts.write[bitmaps[i].chart_index].final_offset = final_pos;
|
||||||
|
charts.write[bitmaps[i].chart_index].transposed = bitmaps[i].transposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atlas_h <= atlas_w * 2 || atlas_w >= atlas_max_width) {
|
||||||
|
break; //ok this one is enough
|
||||||
|
}
|
||||||
|
|
||||||
|
//try again
|
||||||
|
atlas_w *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_width = atlas_w * divide_by;
|
||||||
|
r_height = atlas_h * divide_by;
|
||||||
|
}
|
45
editor/editor_atlas_packer.h
Normal file
45
editor/editor_atlas_packer.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef EDITOR_ATLAS_PACKER_H
|
||||||
|
#define EDITOR_ATLAS_PACKER_H
|
||||||
|
|
||||||
|
#include "core/math/vector2.h"
|
||||||
|
|
||||||
|
#include "core/vector.h"
|
||||||
|
#include "scene/resources/bit_map.h"
|
||||||
|
|
||||||
|
class EditorAtlasPacker {
|
||||||
|
public:
|
||||||
|
struct Chart {
|
||||||
|
Vector<Vector2> vertices;
|
||||||
|
struct Face {
|
||||||
|
int vertex[3];
|
||||||
|
};
|
||||||
|
Vector<Face> faces;
|
||||||
|
bool can_transpose;
|
||||||
|
|
||||||
|
Vector2 final_offset;
|
||||||
|
bool transposed;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct PlottedBitmap {
|
||||||
|
int chart_index;
|
||||||
|
Vector2i offset;
|
||||||
|
int area;
|
||||||
|
Vector<int> top_heights;
|
||||||
|
Vector<int> bottom_heights;
|
||||||
|
bool transposed;
|
||||||
|
|
||||||
|
Vector2 final_pos;
|
||||||
|
|
||||||
|
bool operator<(const PlottedBitmap &p_bm) const {
|
||||||
|
return area > p_bm.area;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _plot_triangle(Ref<BitMap> p_bitmap, Vector2i *vertices);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void chart_pack(Vector<Chart> &charts, int &r_width, int &r_height, int p_atlas_max_size = 2048, int p_cell_resolution = 4);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDITOR_ATLAS_PACKER_H
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
EditorFileSystem *EditorFileSystem::singleton = NULL;
|
EditorFileSystem *EditorFileSystem::singleton = NULL;
|
||||||
//the name is the version, to keep compatibility with different versions of Godot
|
//the name is the version, to keep compatibility with different versions of Godot
|
||||||
#define CACHE_FILE_NAME "filesystem_cache5"
|
#define CACHE_FILE_NAME "filesystem_cache6"
|
||||||
|
|
||||||
void EditorFileSystemDirectory::sort_files() {
|
void EditorFileSystemDirectory::sort_files() {
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ void EditorFileSystem::_scan_filesystem() {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Vector<String> split = l.split("::");
|
Vector<String> split = l.split("::");
|
||||||
ERR_CONTINUE(split.size() != 7);
|
ERR_CONTINUE(split.size() != 8);
|
||||||
String name = split[0];
|
String name = split[0];
|
||||||
String file;
|
String file;
|
||||||
|
|
||||||
|
@ -253,11 +253,12 @@ void EditorFileSystem::_scan_filesystem() {
|
||||||
fc.modification_time = split[2].to_int64();
|
fc.modification_time = split[2].to_int64();
|
||||||
fc.import_modification_time = split[3].to_int64();
|
fc.import_modification_time = split[3].to_int64();
|
||||||
fc.import_valid = split[4].to_int64() != 0;
|
fc.import_valid = split[4].to_int64() != 0;
|
||||||
fc.script_class_name = split[5].get_slice("<>", 0);
|
fc.import_group_file = split[5].strip_edges();
|
||||||
fc.script_class_extends = split[5].get_slice("<>", 1);
|
fc.script_class_name = split[6].get_slice("<>", 0);
|
||||||
fc.script_class_icon_path = split[5].get_slice("<>", 2);
|
fc.script_class_extends = split[6].get_slice("<>", 1);
|
||||||
|
fc.script_class_icon_path = split[6].get_slice("<>", 2);
|
||||||
|
|
||||||
String deps = split[6].strip_edges();
|
String deps = split[7].strip_edges();
|
||||||
if (deps.length()) {
|
if (deps.length()) {
|
||||||
Vector<String> dp = deps.split("<>");
|
Vector<String> dp = deps.split("<>");
|
||||||
for (int i = 0; i < dp.size(); i++) {
|
for (int i = 0; i < dp.size(); i++) {
|
||||||
|
@ -318,6 +319,9 @@ void EditorFileSystem::_scan_filesystem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorFileSystem::_save_filesystem_cache() {
|
void EditorFileSystem::_save_filesystem_cache() {
|
||||||
|
|
||||||
|
group_file_cache.clear();
|
||||||
|
|
||||||
String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME);
|
String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME);
|
||||||
|
|
||||||
FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE);
|
FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE);
|
||||||
|
@ -771,6 +775,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
|
||||||
|
|
||||||
fi->import_valid = fc->import_valid;
|
fi->import_valid = fc->import_valid;
|
||||||
fi->script_class_name = fc->script_class_name;
|
fi->script_class_name = fc->script_class_name;
|
||||||
|
fi->import_group_file = fc->import_group_file;
|
||||||
fi->script_class_extends = fc->script_class_extends;
|
fi->script_class_extends = fc->script_class_extends;
|
||||||
fi->script_class_icon_path = fc->script_class_icon_path;
|
fi->script_class_icon_path = fc->script_class_icon_path;
|
||||||
|
|
||||||
|
@ -784,6 +789,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
|
||||||
|
|
||||||
if (fc->type == String()) {
|
if (fc->type == String()) {
|
||||||
fi->type = ResourceLoader::get_resource_type(path);
|
fi->type = ResourceLoader::get_resource_type(path);
|
||||||
|
fi->import_group_file = ResourceLoader::get_import_group_file(path);
|
||||||
//there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?)
|
//there is also the chance that file type changed due to reimport, must probably check this somehow here (or kind of note it for next time in another file?)
|
||||||
//note: I think this should not happen any longer..
|
//note: I think this should not happen any longer..
|
||||||
}
|
}
|
||||||
|
@ -791,6 +797,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path);
|
fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path);
|
||||||
|
fi->import_group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(path);
|
||||||
fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path);
|
fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path);
|
||||||
fi->modified_time = 0;
|
fi->modified_time = 0;
|
||||||
fi->import_modified_time = 0;
|
fi->import_modified_time = 0;
|
||||||
|
@ -918,6 +925,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
|
||||||
fi->type = ResourceLoader::get_resource_type(path);
|
fi->type = ResourceLoader::get_resource_type(path);
|
||||||
fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path);
|
fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path);
|
||||||
fi->import_valid = ResourceLoader::is_import_valid(path);
|
fi->import_valid = ResourceLoader::is_import_valid(path);
|
||||||
|
fi->import_group_file = ResourceLoader::get_import_group_file(path);
|
||||||
|
|
||||||
{
|
{
|
||||||
ItemAction ia;
|
ItemAction ia;
|
||||||
|
@ -1187,7 +1195,10 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir,
|
||||||
|
|
||||||
for (int i = 0; i < p_dir->files.size(); i++) {
|
for (int i = 0; i < p_dir->files.size(); i++) {
|
||||||
|
|
||||||
String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path;
|
if (p_dir->files[i]->import_group_file != String()) {
|
||||||
|
group_file_cache.insert(p_dir->files[i]->import_group_file);
|
||||||
|
}
|
||||||
|
String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->import_group_file + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path;
|
||||||
s += "::";
|
s += "::";
|
||||||
for (int j = 0; j < p_dir->files[i]->deps.size(); j++) {
|
for (int j = 0; j < p_dir->files[i]->deps.size(); j++) {
|
||||||
|
|
||||||
|
@ -1523,6 +1534,7 @@ void EditorFileSystem::update_file(const String &p_file) {
|
||||||
|
|
||||||
fs->files[cpos]->type = type;
|
fs->files[cpos]->type = type;
|
||||||
fs->files[cpos]->script_class_name = _get_global_script_class(type, p_file, &fs->files[cpos]->script_class_extends, &fs->files[cpos]->script_class_icon_path);
|
fs->files[cpos]->script_class_name = _get_global_script_class(type, p_file, &fs->files[cpos]->script_class_extends, &fs->files[cpos]->script_class_icon_path);
|
||||||
|
fs->files[cpos]->import_group_file = ResourceLoader::get_import_group_file(p_file);
|
||||||
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
|
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
|
||||||
fs->files[cpos]->deps = _get_dependencies(p_file);
|
fs->files[cpos]->deps = _get_dependencies(p_file);
|
||||||
fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file);
|
fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file);
|
||||||
|
@ -1534,6 +1546,168 @@ void EditorFileSystem::update_file(const String &p_file) {
|
||||||
_queue_update_script_classes();
|
_queue_update_script_classes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector<String> &p_files) {
|
||||||
|
|
||||||
|
String importer_name;
|
||||||
|
|
||||||
|
Map<String, Map<StringName, Variant> > source_file_options;
|
||||||
|
Map<String, String> base_paths;
|
||||||
|
for (int i = 0; i < p_files.size(); i++) {
|
||||||
|
|
||||||
|
Ref<ConfigFile> config;
|
||||||
|
config.instance();
|
||||||
|
Error err = config->load(p_files[i] + ".import");
|
||||||
|
ERR_CONTINUE(err != OK);
|
||||||
|
ERR_CONTINUE(!config->has_section_key("remap", "importer"));
|
||||||
|
String file_importer_name = config->get_value("remap", "importer");
|
||||||
|
ERR_CONTINUE(file_importer_name == String());
|
||||||
|
|
||||||
|
if (importer_name != String() && importer_name != file_importer_name) {
|
||||||
|
print_line("one importer: " + importer_name + " the other: " + file_importer_name);
|
||||||
|
EditorNode::get_singleton()->show_warning(vformat(TTR("There are multiple importers for different types pointing to file %s, import aborted"), p_group_file));
|
||||||
|
ERR_FAIL_V(ERR_FILE_CORRUPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
source_file_options[p_files[i]] = Map<StringName, Variant>();
|
||||||
|
importer_name = file_importer_name;
|
||||||
|
|
||||||
|
Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
|
||||||
|
ERR_FAIL_COND_V(!importer.is_valid(), ERR_FILE_CORRUPT);
|
||||||
|
List<ResourceImporter::ImportOption> options;
|
||||||
|
importer->get_import_options(&options);
|
||||||
|
//set default values
|
||||||
|
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
|
||||||
|
|
||||||
|
source_file_options[p_files[i]][E->get().option.name] = E->get().default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->has_section("params")) {
|
||||||
|
List<String> sk;
|
||||||
|
config->get_section_keys("params", &sk);
|
||||||
|
for (List<String>::Element *E = sk.front(); E; E = E->next()) {
|
||||||
|
String param = E->get();
|
||||||
|
Variant value = config->get_value("params", param);
|
||||||
|
//override with whathever is in file
|
||||||
|
source_file_options[p_files[i]][param] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base_paths[p_files[i]] = ResourceFormatImporter::get_singleton()->get_import_base_path(p_files[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(importer_name == String(), ERR_UNCONFIGURED);
|
||||||
|
|
||||||
|
Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
|
||||||
|
|
||||||
|
Error err = importer->import_group_file(p_group_file, source_file_options, base_paths);
|
||||||
|
|
||||||
|
//all went well, overwrite config files with proper remaps and md5s
|
||||||
|
for (Map<String, Map<StringName, Variant> >::Element *E = source_file_options.front(); E; E = E->next()) {
|
||||||
|
|
||||||
|
String file = E->key();
|
||||||
|
String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(file);
|
||||||
|
FileAccessRef f = FileAccess::open(file + ".import", FileAccess::WRITE);
|
||||||
|
ERR_FAIL_COND_V(!f, ERR_FILE_CANT_OPEN);
|
||||||
|
|
||||||
|
//write manually, as order matters ([remap] has to go first for performance).
|
||||||
|
f->store_line("[remap]");
|
||||||
|
f->store_line("");
|
||||||
|
f->store_line("importer=\"" + importer->get_importer_name() + "\"");
|
||||||
|
if (importer->get_resource_type() != "") {
|
||||||
|
f->store_line("type=\"" + importer->get_resource_type() + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> dest_paths;
|
||||||
|
|
||||||
|
if (err == OK) {
|
||||||
|
String path = base_path + "." + importer->get_save_extension();
|
||||||
|
f->store_line("path=\"" + path + "\"");
|
||||||
|
dest_paths.push_back(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
f->store_line("group_file=" + Variant(p_group_file).get_construct_string());
|
||||||
|
|
||||||
|
if (err == OK) {
|
||||||
|
f->store_line("valid=true");
|
||||||
|
} else {
|
||||||
|
f->store_line("valid=false");
|
||||||
|
}
|
||||||
|
f->store_line("[deps]\n");
|
||||||
|
|
||||||
|
f->store_line("");
|
||||||
|
|
||||||
|
f->store_line("source_file=" + Variant(file).get_construct_string());
|
||||||
|
if (dest_paths.size()) {
|
||||||
|
Array dp;
|
||||||
|
for (int i = 0; i < dest_paths.size(); i++) {
|
||||||
|
dp.push_back(dest_paths[i]);
|
||||||
|
}
|
||||||
|
f->store_line("dest_files=" + Variant(dp).get_construct_string() + "\n");
|
||||||
|
}
|
||||||
|
f->store_line("[params]");
|
||||||
|
f->store_line("");
|
||||||
|
|
||||||
|
//store options in provided order, to avoid file changing. Order is also important because first match is accepted first.
|
||||||
|
|
||||||
|
List<ResourceImporter::ImportOption> options;
|
||||||
|
importer->get_import_options(&options);
|
||||||
|
//set default values
|
||||||
|
for (List<ResourceImporter::ImportOption>::Element *F = options.front(); F; F = F->next()) {
|
||||||
|
|
||||||
|
String base = F->get().option.name;
|
||||||
|
Variant v = F->get().default_value;
|
||||||
|
if (source_file_options[file].has(base)) {
|
||||||
|
v = source_file_options[file][base];
|
||||||
|
}
|
||||||
|
String value;
|
||||||
|
VariantWriter::write_to_string(v, value);
|
||||||
|
f->store_line(base + "=" + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
f->close();
|
||||||
|
|
||||||
|
// Store the md5's of the various files. These are stored separately so that the .import files can be version controlled.
|
||||||
|
FileAccessRef md5s = FileAccess::open(base_path + ".md5", FileAccess::WRITE);
|
||||||
|
ERR_FAIL_COND_V(!md5s, ERR_FILE_CANT_OPEN);
|
||||||
|
|
||||||
|
md5s->store_line("source_md5=\"" + FileAccess::get_md5(file) + "\"");
|
||||||
|
if (dest_paths.size()) {
|
||||||
|
md5s->store_line("dest_md5=\"" + FileAccess::get_multiple_md5(dest_paths) + "\"\n");
|
||||||
|
}
|
||||||
|
md5s->close();
|
||||||
|
|
||||||
|
EditorFileSystemDirectory *fs = NULL;
|
||||||
|
int cpos = -1;
|
||||||
|
bool found = _find_file(file, &fs, cpos);
|
||||||
|
ERR_FAIL_COND_V(!found, ERR_UNCONFIGURED);
|
||||||
|
|
||||||
|
//update modified times, to avoid reimport
|
||||||
|
fs->files[cpos]->modified_time = FileAccess::get_modified_time(file);
|
||||||
|
fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(file + ".import");
|
||||||
|
fs->files[cpos]->deps = _get_dependencies(file);
|
||||||
|
fs->files[cpos]->type = importer->get_resource_type();
|
||||||
|
fs->files[cpos]->import_valid = err == OK;
|
||||||
|
|
||||||
|
//if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it
|
||||||
|
//to reload properly
|
||||||
|
if (ResourceCache::has(file)) {
|
||||||
|
|
||||||
|
Resource *r = ResourceCache::get(file);
|
||||||
|
|
||||||
|
if (r->get_import_path() != String()) {
|
||||||
|
|
||||||
|
String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(file);
|
||||||
|
r->set_import_path(dst_path);
|
||||||
|
r->set_import_last_modified_time(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorResourcePreview::get_singleton()->check_for_invalidation(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
void EditorFileSystem::_reimport_file(const String &p_file) {
|
void EditorFileSystem::_reimport_file(const String &p_file) {
|
||||||
|
|
||||||
EditorFileSystemDirectory *fs = NULL;
|
EditorFileSystemDirectory *fs = NULL;
|
||||||
|
@ -1738,6 +1912,24 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
|
||||||
EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
|
EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, Map<String, Vector<String> > &group_files, Set<String> &groups_to_reimport) {
|
||||||
|
|
||||||
|
int fc = efd->files.size();
|
||||||
|
const EditorFileSystemDirectory::FileInfo *const *files = efd->files.ptr();
|
||||||
|
for (int i = 0; i < fc; i++) {
|
||||||
|
if (groups_to_reimport.has(files[i]->import_group_file)) {
|
||||||
|
if (!group_files.has(files[i]->import_group_file)) {
|
||||||
|
group_files[files[i]->import_group_file] = Vector<String>();
|
||||||
|
}
|
||||||
|
group_files[files[i]->import_group_file].push_back(efd->get_file_path(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < efd->get_subdir_count(); i++) {
|
||||||
|
_find_group_files(efd->get_subdir(i), group_files, groups_to_reimport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
|
void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
|
||||||
|
|
||||||
{ //check that .import folder exists
|
{ //check that .import folder exists
|
||||||
|
@ -1757,22 +1949,58 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
|
||||||
EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size());
|
EditorProgress pr("reimport", TTR("(Re)Importing Assets"), p_files.size());
|
||||||
|
|
||||||
Vector<ImportFile> files;
|
Vector<ImportFile> files;
|
||||||
|
Set<String> groups_to_reimport;
|
||||||
|
|
||||||
for (int i = 0; i < p_files.size(); i++) {
|
for (int i = 0; i < p_files.size(); i++) {
|
||||||
ImportFile ifile;
|
|
||||||
ifile.path = p_files[i];
|
String group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(p_files[i]);
|
||||||
ifile.order = ResourceFormatImporter::get_singleton()->get_import_order(p_files[i]);
|
|
||||||
files.push_back(ifile);
|
if (group_file_cache.has(p_files[i])) {
|
||||||
|
//maybe the file itself is a group!
|
||||||
|
groups_to_reimport.insert(p_files[i]);
|
||||||
|
//groups do not belong to grups
|
||||||
|
group_file = String();
|
||||||
|
} else if (group_file != String()) {
|
||||||
|
//it's a group file, add group to import and skip this file
|
||||||
|
groups_to_reimport.insert(group_file);
|
||||||
|
} else {
|
||||||
|
//it's a regular file
|
||||||
|
ImportFile ifile;
|
||||||
|
ifile.path = p_files[i];
|
||||||
|
ifile.order = ResourceFormatImporter::get_singleton()->get_import_order(p_files[i]);
|
||||||
|
files.push_back(ifile);
|
||||||
|
}
|
||||||
|
|
||||||
|
//group may have changed, so also update group reference
|
||||||
|
EditorFileSystemDirectory *fs = NULL;
|
||||||
|
int cpos = -1;
|
||||||
|
if (_find_file(p_files[i], &fs, cpos)) {
|
||||||
|
|
||||||
|
fs->files.write[cpos]->import_group_file = group_file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
files.sort();
|
files.sort();
|
||||||
|
|
||||||
for (int i = 0; i < files.size(); i++) {
|
for (int i = 0; i < files.size(); i++) {
|
||||||
pr.step(files[i].path.get_file(), i);
|
pr.step(files[i].path.get_file(), i);
|
||||||
|
|
||||||
_reimport_file(files[i].path);
|
_reimport_file(files[i].path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//reimport groups
|
||||||
|
|
||||||
|
if (groups_to_reimport.size()) {
|
||||||
|
Map<String, Vector<String> > group_files;
|
||||||
|
_find_group_files(filesystem, group_files, groups_to_reimport);
|
||||||
|
for (Map<String, Vector<String> >::Element *E = group_files.front(); E; E = E->next()) {
|
||||||
|
|
||||||
|
Error err = _reimport_group(E->key(), E->get());
|
||||||
|
if (err == OK) {
|
||||||
|
_reimport_file(E->key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_save_filesystem_cache();
|
_save_filesystem_cache();
|
||||||
importing = false;
|
importing = false;
|
||||||
if (!is_scanning()) {
|
if (!is_scanning()) {
|
||||||
|
@ -1793,6 +2021,63 @@ Error EditorFileSystem::_resource_import(const String &p_path) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EditorFileSystem::is_group_file(const String &p_path) const {
|
||||||
|
return group_file_cache.has(p_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorFileSystem::_move_group_files(EditorFileSystemDirectory *efd, const String &p_group_file, const String &p_new_location) {
|
||||||
|
|
||||||
|
int fc = efd->files.size();
|
||||||
|
EditorFileSystemDirectory::FileInfo *const *files = efd->files.ptrw();
|
||||||
|
for (int i = 0; i < fc; i++) {
|
||||||
|
|
||||||
|
if (files[i]->import_group_file == p_group_file) {
|
||||||
|
|
||||||
|
files[i]->import_group_file = p_new_location;
|
||||||
|
|
||||||
|
Ref<ConfigFile> config;
|
||||||
|
config.instance();
|
||||||
|
String path = efd->get_file_path(i) + ".import";
|
||||||
|
Error err = config->load(path);
|
||||||
|
if (err != OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (config->has_section_key("remap", "group_file")) {
|
||||||
|
|
||||||
|
config->set_value("remap", "group_file", p_new_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> sk;
|
||||||
|
config->get_section_keys("params", &sk);
|
||||||
|
for (List<String>::Element *E = sk.front(); E; E = E->next()) {
|
||||||
|
//not very clean, but should work
|
||||||
|
String param = E->get();
|
||||||
|
String value = config->get_value("params", param);
|
||||||
|
if (value == p_group_file) {
|
||||||
|
config->set_value("params", param, p_new_location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config->save(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < efd->get_subdir_count(); i++) {
|
||||||
|
_move_group_files(efd->get_subdir(i), p_group_file, p_new_location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorFileSystem::move_group_file(const String &p_path, const String &p_new_path) {
|
||||||
|
|
||||||
|
if (get_filesystem()) {
|
||||||
|
_move_group_files(get_filesystem(), p_path, p_new_path);
|
||||||
|
if (group_file_cache.has(p_path)) {
|
||||||
|
group_file_cache.erase(p_path);
|
||||||
|
group_file_cache.insert(p_new_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EditorFileSystem::_bind_methods() {
|
void EditorFileSystem::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_filesystem"), &EditorFileSystem::get_filesystem);
|
ClassDB::bind_method(D_METHOD("get_filesystem"), &EditorFileSystem::get_filesystem);
|
||||||
|
|
|
@ -56,6 +56,7 @@ class EditorFileSystemDirectory : public Object {
|
||||||
uint64_t modified_time;
|
uint64_t modified_time;
|
||||||
uint64_t import_modified_time;
|
uint64_t import_modified_time;
|
||||||
bool import_valid;
|
bool import_valid;
|
||||||
|
String import_group_file;
|
||||||
Vector<String> deps;
|
Vector<String> deps;
|
||||||
bool verified; //used for checking changes
|
bool verified; //used for checking changes
|
||||||
String script_class_name;
|
String script_class_name;
|
||||||
|
@ -167,6 +168,7 @@ class EditorFileSystem : public Node {
|
||||||
uint64_t import_modification_time;
|
uint64_t import_modification_time;
|
||||||
Vector<String> deps;
|
Vector<String> deps;
|
||||||
bool import_valid;
|
bool import_valid;
|
||||||
|
String import_group_file;
|
||||||
String script_class_name;
|
String script_class_name;
|
||||||
String script_class_extends;
|
String script_class_extends;
|
||||||
String script_class_icon_path;
|
String script_class_icon_path;
|
||||||
|
@ -211,6 +213,7 @@ class EditorFileSystem : public Node {
|
||||||
void _update_extensions();
|
void _update_extensions();
|
||||||
|
|
||||||
void _reimport_file(const String &p_file);
|
void _reimport_file(const String &p_file);
|
||||||
|
Error _reimport_group(const String &p_group_file, const Vector<String> &p_files);
|
||||||
|
|
||||||
bool _test_for_reimport(const String &p_path, bool p_only_imported_files);
|
bool _test_for_reimport(const String &p_path, bool p_only_imported_files);
|
||||||
|
|
||||||
|
@ -236,6 +239,12 @@ class EditorFileSystem : public Node {
|
||||||
|
|
||||||
bool using_fat_32; //workaround for projects in FAT32 filesystem (pendrives, most of the time)
|
bool using_fat_32; //workaround for projects in FAT32 filesystem (pendrives, most of the time)
|
||||||
|
|
||||||
|
void _find_group_files(EditorFileSystemDirectory *efd, Map<String, Vector<String> > &group_files, Set<String> &groups_to_reimport);
|
||||||
|
|
||||||
|
void _move_group_files(EditorFileSystemDirectory *efd, const String &p_group_file, const String &p_new_location);
|
||||||
|
|
||||||
|
Set<String> group_file_cache;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -260,6 +269,9 @@ public:
|
||||||
|
|
||||||
void update_script_classes();
|
void update_script_classes();
|
||||||
|
|
||||||
|
bool is_group_file(const String &p_path) const;
|
||||||
|
void move_group_file(const String &p_path, const String &p_new_path);
|
||||||
|
|
||||||
EditorFileSystem();
|
EditorFileSystem();
|
||||||
~EditorFileSystem();
|
~EditorFileSystem();
|
||||||
};
|
};
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include "editor/import/resource_importer_obj.h"
|
#include "editor/import/resource_importer_obj.h"
|
||||||
#include "editor/import/resource_importer_scene.h"
|
#include "editor/import/resource_importer_scene.h"
|
||||||
#include "editor/import/resource_importer_texture.h"
|
#include "editor/import/resource_importer_texture.h"
|
||||||
|
#include "editor/import/resource_importer_texture_atlas.h"
|
||||||
#include "editor/import/resource_importer_wav.h"
|
#include "editor/import/resource_importer_wav.h"
|
||||||
#include "editor/plugins/animation_blend_space_1d_editor.h"
|
#include "editor/plugins/animation_blend_space_1d_editor.h"
|
||||||
#include "editor/plugins/animation_blend_space_2d_editor.h"
|
#include "editor/plugins/animation_blend_space_2d_editor.h"
|
||||||
|
@ -5121,6 +5122,10 @@ EditorNode::EditorNode() {
|
||||||
import_image.instance();
|
import_image.instance();
|
||||||
ResourceFormatImporter::get_singleton()->add_importer(import_image);
|
ResourceFormatImporter::get_singleton()->add_importer(import_image);
|
||||||
|
|
||||||
|
Ref<ResourceImporterTextureAtlas> import_texture_atlas;
|
||||||
|
import_texture_atlas.instance();
|
||||||
|
ResourceFormatImporter::get_singleton()->add_importer(import_texture_atlas);
|
||||||
|
|
||||||
Ref<ResourceImporterCSVTranslation> import_csv_translation;
|
Ref<ResourceImporterCSVTranslation> import_csv_translation;
|
||||||
import_csv_translation.instance();
|
import_csv_translation.instance();
|
||||||
ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation);
|
ResourceFormatImporter::get_singleton()->add_importer(import_csv_translation);
|
||||||
|
|
|
@ -2993,13 +2993,17 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
|
||||||
EditorPropertyClassName *editor = memnew(EditorPropertyClassName);
|
EditorPropertyClassName *editor = memnew(EditorPropertyClassName);
|
||||||
editor->setup("Object", p_hint_text);
|
editor->setup("Object", p_hint_text);
|
||||||
add_property_editor(p_path, editor);
|
add_property_editor(p_path, editor);
|
||||||
} else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) {
|
} else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) {
|
||||||
|
|
||||||
Vector<String> extensions = p_hint_text.split(",");
|
Vector<String> extensions = p_hint_text.split(",");
|
||||||
bool global = p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE;
|
bool global = p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE;
|
||||||
bool folder = p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_GLOBAL_DIR;
|
bool folder = p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_GLOBAL_DIR;
|
||||||
|
bool save = p_hint == PROPERTY_HINT_SAVE_FILE;
|
||||||
EditorPropertyPath *editor = memnew(EditorPropertyPath);
|
EditorPropertyPath *editor = memnew(EditorPropertyPath);
|
||||||
editor->setup(extensions, folder, global);
|
editor->setup(extensions, folder, global);
|
||||||
|
if (save) {
|
||||||
|
editor->set_save_mode();
|
||||||
|
}
|
||||||
add_property_editor(p_path, editor);
|
add_property_editor(p_path, editor);
|
||||||
} else if (p_hint == PROPERTY_HINT_METHOD_OF_VARIANT_TYPE ||
|
} else if (p_hint == PROPERTY_HINT_METHOD_OF_VARIANT_TYPE ||
|
||||||
p_hint == PROPERTY_HINT_METHOD_OF_BASE_TYPE ||
|
p_hint == PROPERTY_HINT_METHOD_OF_BASE_TYPE ||
|
||||||
|
|
|
@ -1257,6 +1257,10 @@ void FileSystemDock::_rename_operation_confirm() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EditorFileSystem::get_singleton()->is_group_file(old_path)) {
|
||||||
|
EditorFileSystem::get_singleton()->move_group_file(old_path, new_path);
|
||||||
|
}
|
||||||
|
|
||||||
//Present a more user friendly warning for name conflict
|
//Present a more user friendly warning for name conflict
|
||||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
|
||||||
#if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED)
|
#if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED)
|
||||||
|
@ -1354,6 +1358,16 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check groups
|
||||||
|
for (int i = 0; i < to_move.size(); i++) {
|
||||||
|
|
||||||
|
print_line("is group: " + to_move[i].path + ": " + itos(EditorFileSystem::get_singleton()->is_group_file(to_move[i].path)));
|
||||||
|
if (to_move[i].is_file && EditorFileSystem::get_singleton()->is_group_file(to_move[i].path)) {
|
||||||
|
print_line("move to: " + p_to_path.plus_file(to_move[i].path.get_file()));
|
||||||
|
EditorFileSystem::get_singleton()->move_group_file(to_move[i].path, p_to_path.plus_file(to_move[i].path.get_file()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, String> file_renames;
|
Map<String, String> file_renames;
|
||||||
Map<String, String> folder_renames;
|
Map<String, String> folder_renames;
|
||||||
bool is_moved = false;
|
bool is_moved = false;
|
||||||
|
|
414
editor/import/atlas_import_failed.xpm
Normal file
414
editor/import/atlas_import_failed.xpm
Normal file
|
@ -0,0 +1,414 @@
|
||||||
|
/* XPM */
|
||||||
|
static const char * atlas_import_failed_xpm[] = {
|
||||||
|
"128 128 283 2",
|
||||||
|
" c None",
|
||||||
|
". c #FFFFFF",
|
||||||
|
"+ c #FFDADA",
|
||||||
|
"@ c #FF0000",
|
||||||
|
"# c #FFD8D8",
|
||||||
|
"$ c #FFF7F7",
|
||||||
|
"% c #FF2E2E",
|
||||||
|
"& c #FFD4D4",
|
||||||
|
"* c #FFD6D6",
|
||||||
|
"= c #FFE3E3",
|
||||||
|
"- c #FFB3B3",
|
||||||
|
"; c #FFC8C8",
|
||||||
|
"> c #FF3535",
|
||||||
|
", c #FF8D8D",
|
||||||
|
"' c #FF7878",
|
||||||
|
") c #FF6E6E",
|
||||||
|
"! c #FFB5B5",
|
||||||
|
"~ c #FF0D0D",
|
||||||
|
"{ c #FFF0F0",
|
||||||
|
"] c #FFE8E8",
|
||||||
|
"^ c #FFC2C2",
|
||||||
|
"/ c #FFEDED",
|
||||||
|
"( c #FFBBBB",
|
||||||
|
"_ c #FFB9B9",
|
||||||
|
": c #FFA4A4",
|
||||||
|
"< c #FFFEFE",
|
||||||
|
"[ c #FFD9D9",
|
||||||
|
"} c #FF9393",
|
||||||
|
"| c #FF5858",
|
||||||
|
"1 c #FF3232",
|
||||||
|
"2 c #FF7575",
|
||||||
|
"3 c #FFC9C9",
|
||||||
|
"4 c #FFFCFC",
|
||||||
|
"5 c #FFBDBD",
|
||||||
|
"6 c #FF3838",
|
||||||
|
"7 c #FF9494",
|
||||||
|
"8 c #FFE2E2",
|
||||||
|
"9 c #FFD1D1",
|
||||||
|
"0 c #FFDEDE",
|
||||||
|
"a c #FFCACA",
|
||||||
|
"b c #FF6969",
|
||||||
|
"c c #FF8484",
|
||||||
|
"d c #FFEAEA",
|
||||||
|
"e c #FFE9E9",
|
||||||
|
"f c #FF3B3B",
|
||||||
|
"g c #FFC0C0",
|
||||||
|
"h c #FF6868",
|
||||||
|
"i c #FF7373",
|
||||||
|
"j c #FFF6F6",
|
||||||
|
"k c #FFADAD",
|
||||||
|
"l c #FF5D5D",
|
||||||
|
"m c #FF2626",
|
||||||
|
"n c #FF5C5C",
|
||||||
|
"o c #FFABAB",
|
||||||
|
"p c #FFCECE",
|
||||||
|
"q c #FF7070",
|
||||||
|
"r c #FF5555",
|
||||||
|
"s c #FF1C1C",
|
||||||
|
"t c #FFF4F4",
|
||||||
|
"u c #FF8282",
|
||||||
|
"v c #FF6060",
|
||||||
|
"w c #FFE7E7",
|
||||||
|
"x c #FF9D9D",
|
||||||
|
"y c #FF5656",
|
||||||
|
"z c #FF4242",
|
||||||
|
"A c #FF9B9B",
|
||||||
|
"B c #FFD0D0",
|
||||||
|
"C c #FFF8F8",
|
||||||
|
"D c #FF6A6A",
|
||||||
|
"E c #FF5151",
|
||||||
|
"F c #FFFBFB",
|
||||||
|
"G c #FF4949",
|
||||||
|
"H c #FFCDCD",
|
||||||
|
"I c #FFDDDD",
|
||||||
|
"J c #FF9E9E",
|
||||||
|
"K c #FFF9F9",
|
||||||
|
"L c #FFDCDC",
|
||||||
|
"M c #FF8F8F",
|
||||||
|
"N c #FFCBCB",
|
||||||
|
"O c #FFF5F5",
|
||||||
|
"P c #FF4747",
|
||||||
|
"Q c #FF9C9C",
|
||||||
|
"R c #FFEEEE",
|
||||||
|
"S c #FFFAFA",
|
||||||
|
"T c #FF1616",
|
||||||
|
"U c #FF8888",
|
||||||
|
"V c #FFC5C5",
|
||||||
|
"W c #FF2222",
|
||||||
|
"X c #FF4B4B",
|
||||||
|
"Y c #FFB8B8",
|
||||||
|
"Z c #FF7F7F",
|
||||||
|
"` c #FFE6E6",
|
||||||
|
" . c #FF8080",
|
||||||
|
".. c #FFB4B4",
|
||||||
|
"+. c #FFC3C3",
|
||||||
|
"@. c #FFD2D2",
|
||||||
|
"#. c #FFD7D7",
|
||||||
|
"$. c #FFDFDF",
|
||||||
|
"%. c #FFB7B7",
|
||||||
|
"&. c #FFF1F1",
|
||||||
|
"*. c #FF6262",
|
||||||
|
"=. c #FF8A8A",
|
||||||
|
"-. c #FFA9A9",
|
||||||
|
";. c #FFAEAE",
|
||||||
|
">. c #FFAAAA",
|
||||||
|
",. c #FF8B8B",
|
||||||
|
"'. c #FF4F4F",
|
||||||
|
"). c #FFFDFD",
|
||||||
|
"!. c #FFA3A3",
|
||||||
|
"~. c #FF2A2A",
|
||||||
|
"{. c #FFCFCF",
|
||||||
|
"]. c #FF8585",
|
||||||
|
"^. c #FF7676",
|
||||||
|
"/. c #FFD3D3",
|
||||||
|
"(. c #FFD5D5",
|
||||||
|
"_. c #FF8181",
|
||||||
|
":. c #FFC6C6",
|
||||||
|
"<. c #FFDBDB",
|
||||||
|
"[. c #FF9090",
|
||||||
|
"}. c #FFAFAF",
|
||||||
|
"|. c #FFA1A1",
|
||||||
|
"1. c #FFBABA",
|
||||||
|
"2. c #FF6C6C",
|
||||||
|
"3. c #FF5F5F",
|
||||||
|
"4. c #FF3D3D",
|
||||||
|
"5. c #FF9999",
|
||||||
|
"6. c #FFE0E0",
|
||||||
|
"7. c #FF8383",
|
||||||
|
"8. c #FFEFEF",
|
||||||
|
"9. c #FFF3F3",
|
||||||
|
"0. c #FFA8A8",
|
||||||
|
"a. c #FFB6B6",
|
||||||
|
"b. c #FF9F9F",
|
||||||
|
"c. c #FF4545",
|
||||||
|
"d. c #FFE5E5",
|
||||||
|
"e. c #FFE4E4",
|
||||||
|
"f. c #FFC7C7",
|
||||||
|
"g. c #FF6565",
|
||||||
|
"h. c #FFACAC",
|
||||||
|
"i. c #FF5A5A",
|
||||||
|
"j. c #FF7272",
|
||||||
|
"k. c #FF7C7C",
|
||||||
|
"l. c #FFBFBF",
|
||||||
|
"m. c #FF7171",
|
||||||
|
"n. c #FFECEC",
|
||||||
|
"o. c #FF8989",
|
||||||
|
"p. c #FF7777",
|
||||||
|
"q. c #FFC4C4",
|
||||||
|
"r. c #FF9898",
|
||||||
|
"s. c #FF8C8C",
|
||||||
|
"t. c #FF7A7A",
|
||||||
|
"u. c #FF8E8E",
|
||||||
|
"v. c #FFF2F2",
|
||||||
|
"w. c #FF9797",
|
||||||
|
"x. c #FFC1C1",
|
||||||
|
"y. c #FFA6A6",
|
||||||
|
"z. c #FFEBEB",
|
||||||
|
"A. c #FF4040",
|
||||||
|
"B. c #EDEDED",
|
||||||
|
"C. c #000000",
|
||||||
|
"D. c #AAAAAA",
|
||||||
|
"E. c #F6F6F6",
|
||||||
|
"F. c #1C1C1C",
|
||||||
|
"G. c #888888",
|
||||||
|
"H. c #7C7C7C",
|
||||||
|
"I. c #626262",
|
||||||
|
"J. c #B3B3B3",
|
||||||
|
"K. c #2A2A2A",
|
||||||
|
"L. c #959595",
|
||||||
|
"M. c #FDFDFD",
|
||||||
|
"N. c #C5C5C5",
|
||||||
|
"O. c #666666",
|
||||||
|
"P. c #353535",
|
||||||
|
"Q. c #777777",
|
||||||
|
"R. c #DEDEDE",
|
||||||
|
"S. c #6C6C6C",
|
||||||
|
"T. c #F5F5F5",
|
||||||
|
"U. c #ADADAD",
|
||||||
|
"V. c #DDDDDD",
|
||||||
|
"W. c #D8D8D8",
|
||||||
|
"X. c #B4B4B4",
|
||||||
|
"Y. c #FAFAFA",
|
||||||
|
"Z. c #949494",
|
||||||
|
"`. c #3B3B3B",
|
||||||
|
" + c #A8A8A8",
|
||||||
|
".+ c #C8C8C8",
|
||||||
|
"++ c #D4D4D4",
|
||||||
|
"@+ c #B9B9B9",
|
||||||
|
"#+ c #2E2E2E",
|
||||||
|
"$+ c #FEFEFE",
|
||||||
|
"%+ c #BABABA",
|
||||||
|
"&+ c #FCFCFC",
|
||||||
|
"*+ c #B2B2B2",
|
||||||
|
"=+ c #CACACA",
|
||||||
|
"-+ c #696969",
|
||||||
|
";+ c #222222",
|
||||||
|
">+ c #F2F2F2",
|
||||||
|
",+ c #555555",
|
||||||
|
"'+ c #C4C4C4",
|
||||||
|
")+ c #EBEBEB",
|
||||||
|
"!+ c #727272",
|
||||||
|
"~+ c #585858",
|
||||||
|
"{+ c #0D0D0D",
|
||||||
|
"]+ c #B1B1B1",
|
||||||
|
"^+ c #E5E5E5",
|
||||||
|
"/+ c #C0C0C0",
|
||||||
|
"(+ c #8F8F8F",
|
||||||
|
"_+ c #4D4D4D",
|
||||||
|
":+ c #F4F4F4",
|
||||||
|
"<+ c #7D7D7D",
|
||||||
|
"[+ c #E4E4E4",
|
||||||
|
"}+ c #F3F3F3",
|
||||||
|
"|+ c #383838",
|
||||||
|
"1+ c #A9A9A9",
|
||||||
|
"2+ c #D6D6D6",
|
||||||
|
"3+ c #D5D5D5",
|
||||||
|
"4+ c #5F5F5F",
|
||||||
|
"5+ c #C6C6C6",
|
||||||
|
"6+ c #E2E2E2",
|
||||||
|
"7+ c #FBFBFB",
|
||||||
|
"8+ c #404040",
|
||||||
|
"9+ c #909090",
|
||||||
|
"0+ c #EEEEEE",
|
||||||
|
"a+ c #878787",
|
||||||
|
"b+ c #E8E8E8",
|
||||||
|
"c+ c #494949",
|
||||||
|
"d+ c #424242",
|
||||||
|
"e+ c #E6E6E6",
|
||||||
|
"f+ c #CFCFCF",
|
||||||
|
"g+ c #DCDCDC",
|
||||||
|
"h+ c #161616",
|
||||||
|
"i+ c #BBBBBB",
|
||||||
|
"j+ c #CCCCCC",
|
||||||
|
"k+ c #B0B0B0",
|
||||||
|
"l+ c #C7C7C7",
|
||||||
|
"m+ c #858585",
|
||||||
|
"n+ c #F8F8F8",
|
||||||
|
"o+ c #D7D7D7",
|
||||||
|
"p+ c #BDBDBD",
|
||||||
|
"q+ c #ECECEC",
|
||||||
|
"r+ c #939393",
|
||||||
|
"s+ c #A1A1A1",
|
||||||
|
"t+ c #7A7A7A",
|
||||||
|
"u+ c #4B4B4B",
|
||||||
|
"v+ c #E9E9E9",
|
||||||
|
"w+ c #717171",
|
||||||
|
"x+ c #AFAFAF",
|
||||||
|
"y+ c #454545",
|
||||||
|
"z+ c #F9F9F9",
|
||||||
|
"A+ c #DBDBDB",
|
||||||
|
"B+ c #C1C1C1",
|
||||||
|
"C+ c #707070",
|
||||||
|
"D+ c #323232",
|
||||||
|
"E+ c #9D9D9D",
|
||||||
|
"F+ c #D1D1D1",
|
||||||
|
"G+ c #6D6D6D",
|
||||||
|
"H+ c #262626",
|
||||||
|
"I+ c #6E6E6E",
|
||||||
|
"J+ c #808080",
|
||||||
|
"K+ c #BFBFBF",
|
||||||
|
"L+ c #999999",
|
||||||
|
"M+ c #F1F1F1",
|
||||||
|
"N+ c #DADADA",
|
||||||
|
"O+ c #9F9F9F",
|
||||||
|
"P+ c #8B8B8B",
|
||||||
|
"Q+ c #7F7F7F",
|
||||||
|
"R+ c #9E9E9E",
|
||||||
|
"S+ c #F0F0F0",
|
||||||
|
"T+ c #A4A4A4",
|
||||||
|
"U+ c #A5A5A5",
|
||||||
|
"V+ c #CDCDCD",
|
||||||
|
"W+ c #CBCBCB",
|
||||||
|
"X+ c #9B9B9B",
|
||||||
|
"Y+ c #D9D9D9",
|
||||||
|
"Z+ c #A0A0A0",
|
||||||
|
"`+ c #9C9C9C",
|
||||||
|
" @ c #C2C2C2",
|
||||||
|
".@ c #636363",
|
||||||
|
"+@ c #D0D0D0",
|
||||||
|
"@@ c #6A6A6A",
|
||||||
|
"#@ c #898989",
|
||||||
|
"$@ c #C3C3C3",
|
||||||
|
"%@ c #A7A7A7",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . $ % @ & . . . . . * @ + . . . . + @ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * @ + . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . ; @ > , . . . . . * @ + . . . . + @ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * @ + . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . ' ) ! ~ { . . . . * @ + . . . . + @ # . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * @ + . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . ] @ ^ / @ ( . . . _ @ @ @ @ @ : . + @ # . . < [ } | 1 2 3 . . . . 4 5 ) 6 | 7 8 . . . . . . . . = @ - . . 9 @ 0 a b > c d . e , f | g . . . . 9 @ 0 a h % i & . . . . j k l m n o j . . . 9 @ 0 p q m r @ @ @ @ @ : . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . k s t . u v < . . _ @ @ @ @ @ : . + @ # . . w @ @ @ @ @ @ 5 . . . k @ @ @ @ @ % . . . . . . . . = @ - . . 9 @ x @ @ @ @ y d z @ @ @ @ * . . . 9 @ A @ @ @ @ @ B . . C D @ @ @ @ @ h C . . 9 @ x @ @ @ E @ @ @ @ @ : . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . F G 7 . . H @ I . . . * @ + . . . . + @ # . . ] J 8 j K 0 h 6 K . . l l = F j L M . . . . . . . . = @ - . . 9 @ % N j O J @ P Q R S & T U . . . 9 @ s ^ O j V W X F . Y @ Z ` S w .@ ... . 9 @ s +.t . . * @ + . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . @.@ #.. . K 6 x . . . * @ + . . . . + @ # . . . . . . . . # @ $.. . ' M . . . . . . . . . . . . . = @ - . . 9 @ %.. . . &.@ *.4 . . . =.r . . . 9 @ -.. . . . ;.@ 0 . q 6 t . . . t f h . . 9 @ >.. . . . * @ + . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . ,.'.).. . . !.~.j . . * @ + . . . . + @ # . . . {.].P ~ @ @ @ 9 . . 8 r ^.- /.j . . . . . . . . . = @ - . . 9 @ + . . . . @ A . . . . !.~ . . . 9 @ (.. . . . # @ N . 1 _.. . . . . c s . . 9 @ (.. . . . * @ + . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . { ~ @ @ @ @ @ @ @ :.. . * @ + . . . . + @ # . . ^ @ @ @ @ @ @ @ H . . . F <._ [.> }.. . . . . . . . = @ - . . 9 @ 0 . . . . @ |.. . . . : @ . . . 9 @ (.. . . . # @ N . 1 u . . . . . c s . . 9 @ 0 . . . . * @ + . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . 1.@ @ @ @ @ @ @ @ ^.. . #.@ # . . . . + @ # . . 2.r $.$ < . [ @ H . . . . . . . + @ * . . . . . . . = @ - . . 9 @ 0 . . . . @ |.. . . . : @ . . . 9 @ -.. . . . ;.@ 0 . q 6 t . . . O f h . . 9 @ 0 . . . . #.@ # . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . < 3.4.K . . . . . 5.@ w . 6.@ ;.F . . . + @ # . . 2.n ` 4 $ + *.@ H . 4 7.@.8.4 9.k @ ^ . . . . . . . = @ - . . 9 @ 0 . . . . @ |.. . . . : @ . . . 9 @ s ^ O j V W X F . %.@ u w F ] u @ - . . 9 @ 0 . . . . 6.@ ;.F . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . L @ 0.. . . . . . L @ o . K > @ @ @ : . + @ # . . a.@ @ @ @ @ b.@ H . F @ @ @ @ @ @ > / . . . . . . . = @ - . . 9 @ 0 . . . . @ |.. . . . : @ . . . 9 @ A @ @ @ @ @ B . . C D @ @ @ @ @ h $ . . 9 @ 0 . . . . K > @ @ @ : . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . A @ ` . . . . . . < *.c.F . # ^.~.@ : . + @ # . . 4 _ *.% q N d.@ H . . e.: h % l b.e . . . . . . . . = @ - . . 9 @ 0 . . . . @ |.. . . . : @ . . . 9 @ 0 f.g.~.i /.. . . . j h.n W i.>.O . . . 9 @ 0 . . . . . # ^.~.@ : . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 @ 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 @ 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 @ 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 @ 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ # . . + @ # . . . . . . . . . . . . . . . . . . . . j.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ @ @ @ @ @ @ # . . . . . . . . . . + @ # . . + @ # . . . . . . . . . . . . . . . . . . . . j.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ @ @ @ @ @ @ # . . . . . . . . . . . . . . . + @ # . . . . . . . . . . . . . . . . . . . . j.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . . . . . . . . . . . . . . . . . + @ # . . . . . . . . . . . . . . . . . . . . j.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . < [ } | 1 2 3 . . . . + @ # . . + @ # . . . 4 l.m.% G 5.n.. . . . &.Q z c.x O j.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . w @ @ @ @ @ @ 5 . . . + @ # . . + @ # . . ).o.@ @ @ @ @ c./ . . $ v @ @ @ @ p.2.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ @ @ @ @ @ U ] J 8 j K 0 h 6 K . . + @ # . . + @ # . . q.@ } w F O q.s r.. . a.@ s.d S 8 ) @ k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ @ @ @ @ @ U . . . . . . # @ $.. . + @ # . . + @ # . . t.| ).. . . . !.> < . q G C . . . d @ k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . . {.].P ~ @ @ @ 9 . . + @ # . . + @ # . . > @ @ @ @ @ @ @ @ O . % u.. . . . . y k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . ^ @ @ @ @ @ @ @ H . . + @ # . . + @ # . . 1 @ @ @ @ @ @ @ @ v.. % u.. . . . . r k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . 2.r $.$ < . [ @ H . . + @ # . . + @ # . . ^.h < . . . . . . . . q G C . . . d @ k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . 2.n ` 4 $ + *.@ H . . + @ # . . + @ # . . +.@ w.e.C S d x.y.. . a.@ s.z.S 8 ) @ k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . a.@ @ @ @ @ b.@ H . . + @ # . . + @ # . . ).M @ @ @ @ @ @ s.. . $ v @ @ @ @ ^.2.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . = @ - . . . . . 4 _ *.% q N d.@ H . . + @ # . . + @ # . . . ).f.k.6 z ' Y v.. . . &.A A.z A O j.k.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.B.C.D.B.C.D.. . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.C.C.C.C.F.. B.C.D.B.C.D.B.C.D.. . . . C.G.. . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.C.H.. . . . . . . B.C.D.B.C.D.. . . . C.G.. . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.C.H.. . . . B.C.D.B.C.D.B.C.D.. . . I.C.C.C.J.B.C.C.C.K.L.M.. N.O.P.Q.R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.C.C.C.C.H.. B.C.D.B.C.D.B.C.D.. . . . C.G.. . B.C.S.T.U.C.V.W.C.X.Y.Z.`.E.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.C.H.. . . . B.C.D.B.C.D.B.C.D.. . . . C.G.. . B.C. +. .+C.++@+C.C.C.C.C.R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.C.H.. . . . B.C.D.B.C.D.B.C.D.. . . . #+Q.$+. B.C.D.. .+C.++W.C.%+&+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.C.H.. . . . B.C.D.B.C.D.B.C.D.. . . . *+`.C.=+B.C.D.. .+C.++. N.-+;+C.C.Y.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . B.C.D.B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y.C.>+,+R.. . '+C.C.)+. . . C.G.. . B.C.D.. . . . . . . . . . . . . . . . E.C.C.C.C.F.. B.C.D.B.C.D.. . . . . . . Y.C.>+,+R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y.C.>+,+R.. . !+~+{+]+. . . C.G.. . B.C.D.. . . . . . . . . . . . . . . . E.C.H.. . . . . . . B.C.D.. . . . . . . Y.C.>+,+R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Y.C.>+,+R.. ^+C./+(+_+&+. I.C.C.C.J.B.C.D.:+C.C.P.<+[+. }+G.|+C.C.>+. . . E.C.H.. . . . B.C.D.B.C.D.. N.O.P.Q.R.. Y.C.>+,+R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1+;+T.2+C.3+. . C.G.. . B.C.D.. . . T.4+Q.. 5+C.X.6+Y.. . . . E.C.C.C.C.H.. B.C.D.B.C.D.W.C.X.Y.Z.`.E.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7+8+C.C.C.C.9+. . C.G.. . B.C.D.0+a+8+C.C.|+. b+c+C.C.d+e+. . . E.C.H.. . . . B.C.D.B.C.D.@+C.C.C.C.C.R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . f+C.g+. . J.h+>+. #+Q.$+. B.C.D.i+C.j+0+,+#+. . &+e+k+C.l+. . . E.C.H.. . . . B.C.D.B.C.D.W.C.%+&+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . m+h+n+. . o+C.p+. *+`.C.=+B.C.D.q+!+{+C.C.#+. =+C.C.8+r+E.. . . E.C.H.. . . . B.C.D.B.C.D.. N.-+;+C.C.Y.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . V.4+C.s+C.U.. . . . . . . B.C.D.. . . . N.C.W.. . . B.C.D.. . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+u+Y.v+C.U.. . . . . . . B.C.D.. . . . N.C.W.. . . B.C.D.. . . . . . . . . . . C.G.. . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u+w+. . . . . . . . . . . B.C.D.. . . . N.C.W.. . . . . . . . . . . . . . . . . C.G.. . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . H.C.C.C.C.C.U.. N.O.P.Q.R.. B.C.D.. x+d+C.C.C.W.. . . B.C.D.B.C.C.C.K.L.M.. . . I.C.C.C.J.B.C.C.C.K.L.M.. N.O.P.Q.R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y+!+. v+C.U.W.C.X.Y.Z.`.E.B.C.D.2+C.x+z+(+C.W.. . . B.C.D.B.C.S.T.U.C.V.. . . . C.G.. . B.C.S.T.U.C.V.W.C.X.Y.Z.`.E.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y+!+. v+C.U.@+C.C.C.C.C.R.B.C.D.%+C.A+. B+C.W.. . . B.C.D.B.C. +. .+C.++. . . . C.G.. . B.C. +. .+C.++@+C.C.C.C.C.R.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y+!+. v+C.U.W.C.%+&+. . . B.C.D.2+C.k+z+9+C.W.. . . B.C.D.B.C.D.. .+C.++. . . . #+Q.$+. B.C.D.. .+C.++W.C.%+&+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . y+!+. v+C.U.. N.-+;+C.C.Y.B.C.D.. x+d+C.C.C.W.. . . B.C.D.B.C.D.. .+C.++. . . . *+`.C.=+B.C.D.. .+C.++. N.-+;+C.C.Y.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . N.C.W.. . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . N.C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.G.. . . . . . . . . N.C.W.. . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . N.C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.G.. . . . . . . . . N.C.W.. . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . N.C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . B.C.D.)+C.C.C.K.C+O.K.!+B.B.C.C.C.D+E+7+. '+O.P.C+F+. B.C.C.C.,+I.C.C.C.J.. . . . x+d+C.C.C.W.. '+O.P.C+F+. . .+G+H+C.R.B.C.D.>+I+I.q+. . . :+C.C.P.<+[+. B.C.C.C.K.L.M.. x+d+C.C.C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . B.C.D.)+C.!+T.J+C.=+g+C.]+B.C.I+E.=+C.K+W.C.]+Y.L+h+b+B.C.O.M+. . C.G.. . . . . 2+C.x+z+(+C.W.W.C.]+Y.L+h+b+N+C.O+z+. . B.C.P+4+Q+T.. . . . . . . T.4+Q.. B.C.S.T.U.C.V.2+C.x+z+(+C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . B.C.D.)+C. +. R+C.M+S+C.T+B.C.U+. M+C.E+@+C.V.. =+C.V+B.C. +. . . C.G.. . . . . %+C.A+. B+C.W.@+C.V.. =+C.V+@+C.A+. . . B.C.C.C.R.. . . . . 0+a+8+C.C.|+. B.C. +. .+C.++%+C.A+. B+C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . B.C.D.)+C.D.. R+C.>+S+C.T+B.C.C+E.W+C.K+W.C.*+Y.X+{+b+B.C.D.. . . #+Q.$+. . . . 2+C.k+z+9+C.W.W.C.*+Y.X+{+b+Y+C.s+z+. . B.C.Z+m+|+V.. . . . i+C.j+0+,+#+. B.C.D.. .+C.++2+C.k+z+9+C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . B.C.D.)+C.D.. R+C.>+S+C.T+B.C.C.C.D+`+7+. @.@D+G++@. B.C.D.. . . *+`.C.=+. . . . x+d+C.C.C.W.. @.@D+G++@. . l+@@H+C.R.B.C.D.Y.#@K.2+. . . q+!+{+C.C.#+. B.C.D.. .+C.++. x+d+C.C.C.W.. . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.G.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.G.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.C.C.,+. N.O.P.Q.R.. . . . . B.C.D.)+C.C.C.K.C+O.K.!+B.B.C.C.C.D+E+7+. '+O.P.C+F+. B.C.C.C.,+I.C.C.C.J.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.O.M+. W.C.X.Y.Z.`.E.$@C.C.%@B.C.D.)+C.!+T.J+C.=+g+C.]+B.C.I+E.=+C.K+W.C.]+Y.L+h+b+B.C.O.M+. . C.G.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C. +. . @+C.C.C.C.C.R.. . . . B.C.D.)+C. +. R+C.M+S+C.T+B.C.U+. M+C.E+@+C.V.. =+C.V+B.C. +. . . C.G.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . W.C.%+&+. . . . . . . B.C.D.)+C.D.. R+C.>+S+C.T+B.C.C+E.W+C.K+W.C.*+Y.X+{+b+B.C.D.. . . #+Q.$+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . N.-+;+C.C.Y.. . . . B.C.D.)+C.D.. R+C.>+S+C.T+B.C.C.C.D+`+7+. @.@D+G++@. B.C.D.. . . *+`.C.=+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.C.D.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
|
||||||
|
". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
|
382
editor/import/resource_importer_texture_atlas.cpp
Normal file
382
editor/import/resource_importer_texture_atlas.cpp
Normal file
|
@ -0,0 +1,382 @@
|
||||||
|
#include "resource_importer_texture_atlas.h"
|
||||||
|
|
||||||
|
#include "atlas_import_failed.xpm"
|
||||||
|
#include "core/io/image_loader.h"
|
||||||
|
#include "core/io/resource_saver.h"
|
||||||
|
#include "core/os/file_access.h"
|
||||||
|
#include "editor/editor_atlas_packer.h"
|
||||||
|
#include "scene/resources/mesh.h"
|
||||||
|
#include "scene/resources/texture.h"
|
||||||
|
|
||||||
|
String ResourceImporterTextureAtlas::get_importer_name() const {
|
||||||
|
|
||||||
|
return "texture_atlas";
|
||||||
|
}
|
||||||
|
|
||||||
|
String ResourceImporterTextureAtlas::get_visible_name() const {
|
||||||
|
|
||||||
|
return "TextureAtlas";
|
||||||
|
}
|
||||||
|
void ResourceImporterTextureAtlas::get_recognized_extensions(List<String> *p_extensions) const {
|
||||||
|
|
||||||
|
ImageLoader::get_recognized_extensions(p_extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
String ResourceImporterTextureAtlas::get_save_extension() const {
|
||||||
|
return "res";
|
||||||
|
}
|
||||||
|
|
||||||
|
String ResourceImporterTextureAtlas::get_resource_type() const {
|
||||||
|
|
||||||
|
return "Texture";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceImporterTextureAtlas::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ResourceImporterTextureAtlas::get_preset_count() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
String ResourceImporterTextureAtlas::get_preset_name(int p_idx) const {
|
||||||
|
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceImporterTextureAtlas::get_import_options(List<ImportOption> *r_options, int p_preset) const {
|
||||||
|
|
||||||
|
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "atlas_file", PROPERTY_HINT_SAVE_FILE, "*.png"), ""));
|
||||||
|
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_mode", PROPERTY_HINT_ENUM, "Region,Mesh2D"), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
String ResourceImporterTextureAtlas::get_option_group_file() const {
|
||||||
|
return "atlas_file";
|
||||||
|
}
|
||||||
|
|
||||||
|
Error ResourceImporterTextureAtlas::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, Variant *r_metadata) {
|
||||||
|
|
||||||
|
/* If this happens, it's because the atlas_file field was not filled, so just import a broken texture */
|
||||||
|
|
||||||
|
//use an xpm because it's size independent, the editor images are vector and size dependent
|
||||||
|
//it's a simple hack
|
||||||
|
Ref<Image> broken = memnew(Image((const char **)atlas_import_failed_xpm));
|
||||||
|
Ref<ImageTexture> broken_texture;
|
||||||
|
broken_texture.instance();
|
||||||
|
broken_texture->create_from_image(broken);
|
||||||
|
|
||||||
|
String target_file = p_save_path + ".tex";
|
||||||
|
|
||||||
|
ResourceSaver::save(target_file, broken_texture);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_transposed, Ref<Image> p_image, const Ref<Image> &p_src_image) {
|
||||||
|
|
||||||
|
int width = p_image->get_width();
|
||||||
|
int height = p_image->get_height();
|
||||||
|
int src_width = p_src_image->get_width();
|
||||||
|
int src_height = p_src_image->get_height();
|
||||||
|
|
||||||
|
int x[3];
|
||||||
|
int y[3];
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
|
||||||
|
x[j] = vertices[j].x;
|
||||||
|
y[j] = vertices[j].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the points vertically
|
||||||
|
if (y[1] > y[2]) {
|
||||||
|
SWAP(x[1], x[2]);
|
||||||
|
SWAP(y[1], y[2]);
|
||||||
|
}
|
||||||
|
if (y[0] > y[1]) {
|
||||||
|
SWAP(x[0], x[1]);
|
||||||
|
SWAP(y[0], y[1]);
|
||||||
|
}
|
||||||
|
if (y[1] > y[2]) {
|
||||||
|
SWAP(x[1], x[2]);
|
||||||
|
SWAP(y[1], y[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
double dx_far = double(x[2] - x[0]) / (y[2] - y[0] + 1);
|
||||||
|
double dx_upper = double(x[1] - x[0]) / (y[1] - y[0] + 1);
|
||||||
|
double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1);
|
||||||
|
double xf = x[0];
|
||||||
|
double xt = x[0] + dx_upper; // if y[0] == y[1], special case
|
||||||
|
for (int yi = y[0]; yi <= (y[2] > height - 1 ? height - 1 : y[2]); yi++) {
|
||||||
|
if (yi >= 0) {
|
||||||
|
for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) {
|
||||||
|
|
||||||
|
int px = xi, py = yi;
|
||||||
|
int sx = px, sy = py;
|
||||||
|
sx = CLAMP(sx, 0, src_width);
|
||||||
|
sy = CLAMP(sy, 0, src_height);
|
||||||
|
Color color = p_src_image->get_pixel(sx, sy);
|
||||||
|
if (p_transposed) {
|
||||||
|
SWAP(px, py);
|
||||||
|
}
|
||||||
|
px += p_offset.x;
|
||||||
|
py += p_offset.y;
|
||||||
|
|
||||||
|
//may have been cropped, so don't blit what is not visible?
|
||||||
|
if (px < 0 || px >= width) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (py < 0 || py >= height) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p_image->set_pixel(px, py, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
|
||||||
|
int px = xi, py = yi;
|
||||||
|
int sx = px, sy = py;
|
||||||
|
sx = CLAMP(sx, 0, src_width);
|
||||||
|
sy = CLAMP(sy, 0, src_height);
|
||||||
|
Color color = p_src_image->get_pixel(sx, sy);
|
||||||
|
if (p_transposed) {
|
||||||
|
SWAP(px, py);
|
||||||
|
}
|
||||||
|
px += p_offset.x;
|
||||||
|
py += p_offset.y;
|
||||||
|
|
||||||
|
//may have been cropped, so don't blit what is not visible?
|
||||||
|
if (px < 0 || px >= width) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (py < 0 || py >= height) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p_image->set_pixel(px, py, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xf += dx_far;
|
||||||
|
if (yi < y[1])
|
||||||
|
xt += dx_upper;
|
||||||
|
else
|
||||||
|
xt += dx_low;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant> > &p_source_file_options, const Map<String, String> &p_base_paths) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(p_source_file_options.size() == 0, ERR_BUG); //should never happen
|
||||||
|
|
||||||
|
Vector<EditorAtlasPacker::Chart> charts;
|
||||||
|
Vector<PackData> pack_data_files;
|
||||||
|
|
||||||
|
pack_data_files.resize(p_source_file_options.size());
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for (const Map<String, Map<StringName, Variant> >::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) {
|
||||||
|
|
||||||
|
PackData &pack_data = pack_data_files.write[idx];
|
||||||
|
String source = E->key();
|
||||||
|
const Map<StringName, Variant> &options = E->get();
|
||||||
|
|
||||||
|
Ref<Image> image;
|
||||||
|
image.instance();
|
||||||
|
Error err = ImageLoader::load_image(source, image);
|
||||||
|
ERR_CONTINUE(err != OK);
|
||||||
|
|
||||||
|
pack_data.image = image;
|
||||||
|
|
||||||
|
int mode = options["import_mode"];
|
||||||
|
|
||||||
|
if (mode == IMPORT_MODE_REGION) {
|
||||||
|
|
||||||
|
pack_data.is_mesh = false;
|
||||||
|
|
||||||
|
EditorAtlasPacker::Chart chart;
|
||||||
|
|
||||||
|
//clip a region from the image
|
||||||
|
Rect2 used_rect = image->get_used_rect();
|
||||||
|
pack_data.region = used_rect;
|
||||||
|
|
||||||
|
chart.vertices.push_back(used_rect.position);
|
||||||
|
chart.vertices.push_back(used_rect.position + Vector2(used_rect.size.x, 0));
|
||||||
|
chart.vertices.push_back(used_rect.position + Vector2(used_rect.size.x, used_rect.size.y));
|
||||||
|
chart.vertices.push_back(used_rect.position + Vector2(0, used_rect.size.y));
|
||||||
|
EditorAtlasPacker::Chart::Face f;
|
||||||
|
f.vertex[0] = 0;
|
||||||
|
f.vertex[1] = 1;
|
||||||
|
f.vertex[2] = 2;
|
||||||
|
chart.faces.push_back(f);
|
||||||
|
f.vertex[0] = 0;
|
||||||
|
f.vertex[1] = 2;
|
||||||
|
f.vertex[2] = 3;
|
||||||
|
chart.faces.push_back(f);
|
||||||
|
chart.can_transpose = false;
|
||||||
|
pack_data.chart_vertices.push_back(chart.vertices);
|
||||||
|
pack_data.chart_pieces.push_back(charts.size());
|
||||||
|
charts.push_back(chart);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pack_data.is_mesh = true;
|
||||||
|
|
||||||
|
Ref<BitMap> bit_map;
|
||||||
|
bit_map.instance();
|
||||||
|
bit_map->create_from_image_alpha(image);
|
||||||
|
Vector<Vector<Vector2> > polygons = bit_map->clip_opaque_to_polygons(Rect2(0, 0, image->get_width(), image->get_height()));
|
||||||
|
|
||||||
|
for (int j = 0; j < polygons.size(); j++) {
|
||||||
|
|
||||||
|
EditorAtlasPacker::Chart chart;
|
||||||
|
chart.vertices = polygons[j];
|
||||||
|
chart.can_transpose = true;
|
||||||
|
|
||||||
|
Vector<int> poly = Geometry::triangulate_polygon(polygons[j]);
|
||||||
|
for (int i = 0; i < poly.size(); i += 3) {
|
||||||
|
|
||||||
|
EditorAtlasPacker::Chart::Face f;
|
||||||
|
f.vertex[0] = poly[i + 0];
|
||||||
|
f.vertex[1] = poly[i + 1];
|
||||||
|
f.vertex[2] = poly[i + 2];
|
||||||
|
chart.faces.push_back(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
pack_data.chart_pieces.push_back(charts.size());
|
||||||
|
charts.push_back(chart);
|
||||||
|
|
||||||
|
pack_data.chart_vertices.push_back(polygons[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//pack the charts
|
||||||
|
int atlas_width, atlas_height;
|
||||||
|
EditorAtlasPacker::chart_pack(charts, atlas_width, atlas_height);
|
||||||
|
|
||||||
|
//blit the atlas
|
||||||
|
Ref<Image> new_atlas;
|
||||||
|
new_atlas.instance();
|
||||||
|
new_atlas->create(atlas_width, atlas_height, false, Image::FORMAT_RGBA8);
|
||||||
|
|
||||||
|
new_atlas->lock();
|
||||||
|
|
||||||
|
for (int i = 0; i < pack_data_files.size(); i++) {
|
||||||
|
|
||||||
|
PackData &pack_data = pack_data_files.write[i];
|
||||||
|
pack_data.image->lock();
|
||||||
|
for (int j = 0; j < pack_data.chart_pieces.size(); j++) {
|
||||||
|
const EditorAtlasPacker::Chart &chart = charts[pack_data.chart_pieces[j]];
|
||||||
|
for (int k = 0; k < chart.faces.size(); k++) {
|
||||||
|
Vector2 positions[3];
|
||||||
|
for (int l = 0; l < 3; l++) {
|
||||||
|
int vertex_idx = chart.faces[k].vertex[l];
|
||||||
|
positions[l] = chart.vertices[vertex_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
_plot_triangle(positions, chart.final_offset, chart.transposed, new_atlas, pack_data.image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pack_data.image->unlock();
|
||||||
|
}
|
||||||
|
new_atlas->unlock();
|
||||||
|
|
||||||
|
//save the atlas
|
||||||
|
|
||||||
|
new_atlas->save_png(p_group_file);
|
||||||
|
|
||||||
|
//update cache if existing, else create
|
||||||
|
Ref<Texture> cache;
|
||||||
|
if (ResourceCache::has(p_group_file)) {
|
||||||
|
Resource *resptr = ResourceCache::get(p_group_file);
|
||||||
|
cache.reference_ptr(resptr);
|
||||||
|
} else {
|
||||||
|
Ref<ImageTexture> res_cache;
|
||||||
|
res_cache.instance();
|
||||||
|
res_cache->create_from_image(new_atlas);
|
||||||
|
res_cache->set_path(p_group_file);
|
||||||
|
cache = res_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the images
|
||||||
|
idx = 0;
|
||||||
|
for (const Map<String, Map<StringName, Variant> >::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) {
|
||||||
|
|
||||||
|
PackData &pack_data = pack_data_files.write[idx];
|
||||||
|
|
||||||
|
Ref<Texture> texture;
|
||||||
|
|
||||||
|
if (!pack_data.is_mesh) {
|
||||||
|
Vector2 offset = charts[pack_data.chart_pieces[0]].vertices[0] + charts[pack_data.chart_pieces[0]].final_offset;
|
||||||
|
|
||||||
|
//region
|
||||||
|
Ref<AtlasTexture> atlas_texture;
|
||||||
|
atlas_texture.instance();
|
||||||
|
atlas_texture->set_atlas(cache);
|
||||||
|
atlas_texture->set_region(Rect2(offset, pack_data.region.size));
|
||||||
|
atlas_texture->set_margin(Rect2(pack_data.region.position, Size2(pack_data.image->get_width(), pack_data.image->get_height()) - pack_data.region.size));
|
||||||
|
|
||||||
|
texture = atlas_texture;
|
||||||
|
} else {
|
||||||
|
Ref<ArrayMesh> mesh;
|
||||||
|
mesh.instance();
|
||||||
|
|
||||||
|
for (int i = 0; i < pack_data.chart_pieces.size(); i++) {
|
||||||
|
const EditorAtlasPacker::Chart &chart = charts[pack_data.chart_pieces[i]];
|
||||||
|
PoolVector<Vector2> vertices;
|
||||||
|
PoolVector<int> indices;
|
||||||
|
PoolVector<Vector2> uvs;
|
||||||
|
int vc = chart.vertices.size();
|
||||||
|
int fc = chart.faces.size();
|
||||||
|
vertices.resize(vc);
|
||||||
|
uvs.resize(vc);
|
||||||
|
indices.resize(fc * 3);
|
||||||
|
|
||||||
|
{
|
||||||
|
PoolVector<Vector2>::Write vw = vertices.write();
|
||||||
|
PoolVector<int>::Write iw = indices.write();
|
||||||
|
PoolVector<Vector2>::Write uvw = uvs.write();
|
||||||
|
|
||||||
|
for (int j = 0; j < vc; j++) {
|
||||||
|
vw[j] = chart.vertices[j];
|
||||||
|
Vector2 uv = chart.vertices[j];
|
||||||
|
if (chart.transposed) {
|
||||||
|
SWAP(uv.x, uv.y);
|
||||||
|
}
|
||||||
|
uv += chart.final_offset;
|
||||||
|
uv /= new_atlas->get_size(); //normalize uv to 0-1 range
|
||||||
|
uvw[j] = uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < fc; j++) {
|
||||||
|
iw[j * 3 + 0] = chart.faces[j].vertex[0];
|
||||||
|
iw[j * 3 + 1] = chart.faces[j].vertex[1];
|
||||||
|
iw[j * 3 + 2] = chart.faces[j].vertex[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array arrays;
|
||||||
|
arrays.resize(Mesh::ARRAY_MAX);
|
||||||
|
arrays[Mesh::ARRAY_VERTEX] = vertices;
|
||||||
|
arrays[Mesh::ARRAY_TEX_UV] = uvs;
|
||||||
|
arrays[Mesh::ARRAY_INDEX] = indices;
|
||||||
|
|
||||||
|
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<MeshTexture> mesh_texture;
|
||||||
|
mesh_texture.instance();
|
||||||
|
mesh_texture->set_base_texture(cache);
|
||||||
|
mesh_texture->set_image_size(pack_data.image->get_size());
|
||||||
|
mesh_texture->set_mesh(mesh);
|
||||||
|
|
||||||
|
texture = mesh_texture;
|
||||||
|
//mesh
|
||||||
|
}
|
||||||
|
|
||||||
|
String save_path = p_base_paths[E->key()] + ".res";
|
||||||
|
ResourceSaver::save(save_path, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceImporterTextureAtlas::ResourceImporterTextureAtlas() {
|
||||||
|
}
|
42
editor/import/resource_importer_texture_atlas.h
Normal file
42
editor/import/resource_importer_texture_atlas.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef RESOURCE_IMPORTER_TEXTURE_ATLAS_H
|
||||||
|
#define RESOURCE_IMPORTER_TEXTURE_ATLAS_H
|
||||||
|
|
||||||
|
#include "core/image.h"
|
||||||
|
#include "core/io/resource_importer.h"
|
||||||
|
class ResourceImporterTextureAtlas : public ResourceImporter {
|
||||||
|
GDCLASS(ResourceImporterTextureAtlas, ResourceImporter)
|
||||||
|
|
||||||
|
struct PackData {
|
||||||
|
Rect2 region;
|
||||||
|
bool is_mesh;
|
||||||
|
Vector<int> chart_pieces; //one for region, many for mesh
|
||||||
|
Vector<Vector<Vector2> > chart_vertices; //for mesh
|
||||||
|
Ref<Image> image;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ImportMode {
|
||||||
|
IMPORT_MODE_REGION,
|
||||||
|
IMPORT_MODE_2D_MESH
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual String get_importer_name() const;
|
||||||
|
virtual String get_visible_name() const;
|
||||||
|
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||||
|
virtual String get_save_extension() const;
|
||||||
|
virtual String get_resource_type() const;
|
||||||
|
|
||||||
|
virtual int get_preset_count() const;
|
||||||
|
virtual String get_preset_name(int p_idx) const;
|
||||||
|
|
||||||
|
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
|
||||||
|
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
|
||||||
|
virtual String get_option_group_file() const;
|
||||||
|
|
||||||
|
virtual Error 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 = NULL, Variant *r_metadata = NULL);
|
||||||
|
virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant> > &p_source_file_options, const Map<String, String> &p_base_paths);
|
||||||
|
|
||||||
|
ResourceImporterTextureAtlas();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RESOURCE_IMPORTER_TEXTURE_ATLAS_H
|
|
@ -438,6 +438,8 @@ void ImportDock::_reimport() {
|
||||||
Error err = config->load(params->paths[i] + ".import");
|
Error err = config->load(params->paths[i] + ".import");
|
||||||
ERR_CONTINUE(err != OK);
|
ERR_CONTINUE(err != OK);
|
||||||
|
|
||||||
|
String importer_name = params->importer->get_importer_name();
|
||||||
|
|
||||||
if (params->checking) {
|
if (params->checking) {
|
||||||
//update only what edited (checkboxes)
|
//update only what edited (checkboxes)
|
||||||
for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
|
for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
|
||||||
|
@ -447,7 +449,7 @@ void ImportDock::_reimport() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//override entirely
|
//override entirely
|
||||||
config->set_value("remap", "importer", params->importer->get_importer_name());
|
config->set_value("remap", "importer", importer_name);
|
||||||
config->erase_section("params");
|
config->erase_section("params");
|
||||||
|
|
||||||
for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
|
for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
|
||||||
|
@ -455,6 +457,19 @@ void ImportDock::_reimport() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//handle group file
|
||||||
|
Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
|
||||||
|
ERR_CONTINUE(!importer.is_valid());
|
||||||
|
String group_file_property = importer->get_option_group_file();
|
||||||
|
if (group_file_property != String()) {
|
||||||
|
//can import from a group (as in, atlas)
|
||||||
|
ERR_CONTINUE(!params->values.has(group_file_property));
|
||||||
|
String group_file = params->values[group_file_property];
|
||||||
|
config->set_value("remap", "group_file", group_file);
|
||||||
|
} else {
|
||||||
|
config->set_value("remap", "group_file", Variant()); //clear group file if unused
|
||||||
|
}
|
||||||
|
|
||||||
config->save(params->paths[i] + ".import");
|
config->save(params->paths[i] + ".import");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -891,13 +891,13 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo
|
||||||
VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, p_antialiased);
|
VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, p_antialiased);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) {
|
void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform, const Color &p_modulate) {
|
||||||
|
|
||||||
ERR_FAIL_COND(p_mesh.is_null());
|
ERR_FAIL_COND(p_mesh.is_null());
|
||||||
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
|
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
|
||||||
RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
|
RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
|
||||||
|
|
||||||
VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), texture_rid, normal_map_rid);
|
VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), p_transform, p_modulate, texture_rid, normal_map_rid);
|
||||||
}
|
}
|
||||||
void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) {
|
void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) {
|
||||||
|
|
||||||
|
@ -1168,7 +1168,7 @@ void CanvasItem::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false));
|
ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false));
|
||||||
ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1));
|
ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1));
|
||||||
ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1)));
|
ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1)));
|
||||||
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()));
|
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()), DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1)));
|
||||||
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture>()));
|
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture>()));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform);
|
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform);
|
||||||
|
|
|
@ -317,7 +317,7 @@ public:
|
||||||
void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
|
void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
|
||||||
void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
|
void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
|
||||||
|
|
||||||
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map);
|
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1));
|
||||||
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map);
|
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map);
|
||||||
|
|
||||||
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1);
|
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1);
|
||||||
|
|
|
@ -635,6 +635,7 @@ void register_scene_types() {
|
||||||
ClassDB::register_class<StreamTexture>();
|
ClassDB::register_class<StreamTexture>();
|
||||||
ClassDB::register_class<ImageTexture>();
|
ClassDB::register_class<ImageTexture>();
|
||||||
ClassDB::register_class<AtlasTexture>();
|
ClassDB::register_class<AtlasTexture>();
|
||||||
|
ClassDB::register_class<MeshTexture>();
|
||||||
ClassDB::register_class<LargeTexture>();
|
ClassDB::register_class<LargeTexture>();
|
||||||
ClassDB::register_class<CurveTexture>();
|
ClassDB::register_class<CurveTexture>();
|
||||||
ClassDB::register_class<GradientTexture>();
|
ClassDB::register_class<GradientTexture>();
|
||||||
|
|
|
@ -595,6 +595,64 @@ Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) con
|
||||||
return result_array;
|
return result_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BitMap::resize(const Size2& p_new_size) {
|
||||||
|
|
||||||
|
Ref<BitMap> new_bitmap;
|
||||||
|
new_bitmap.instance();
|
||||||
|
new_bitmap->create(p_new_size);
|
||||||
|
int lw = MIN(width,p_new_size.width);
|
||||||
|
int lh = MIN(height,p_new_size.height);
|
||||||
|
for(int x=0;x<lw;x++) {
|
||||||
|
for(int y=0;y<lh;y++) {
|
||||||
|
new_bitmap->set_bit(Vector2(x,y),get_bit(Vector2(x,y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width = new_bitmap->width;
|
||||||
|
height = new_bitmap->height;
|
||||||
|
bitmask = new_bitmap->bitmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Image> BitMap::convert_to_image() const {
|
||||||
|
|
||||||
|
Ref<Image> image;
|
||||||
|
image.instance();
|
||||||
|
image->create(width,height,false,Image::FORMAT_L8);
|
||||||
|
image->lock();
|
||||||
|
for(int i=0;i<width;i++) {
|
||||||
|
for(int j=0;j<height;j++) {
|
||||||
|
image->set_pixel( i,j,get_bit(Point2(i,j)) ? Color(1,1,1) : Color(0,0,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image->unlock();
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
void BitMap::blit(const Vector2& p_pos,const Ref<BitMap>& p_bitmap) {
|
||||||
|
|
||||||
|
int x = p_pos.x;
|
||||||
|
int y = p_pos.y;
|
||||||
|
int w = p_bitmap->get_size().width;
|
||||||
|
int h = p_bitmap->get_size().height;
|
||||||
|
|
||||||
|
for(int i=0;i<w;i++) {
|
||||||
|
for (int j=0;j<h;j++) {
|
||||||
|
int px = x+i;
|
||||||
|
int py = y+j;
|
||||||
|
if (px<0 || px>=width)
|
||||||
|
continue;
|
||||||
|
if (py<0 || py>=height)
|
||||||
|
continue;
|
||||||
|
if (p_bitmap->get_bit(Vector2(i,j))) {
|
||||||
|
set_bit(Vector2(x,y),true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BitMap::_bind_methods() {
|
void BitMap::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create);
|
ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create);
|
||||||
|
|
|
@ -64,9 +64,13 @@ public:
|
||||||
int get_true_bit_count() const;
|
int get_true_bit_count() const;
|
||||||
|
|
||||||
Size2 get_size() const;
|
Size2 get_size() const;
|
||||||
|
void resize(const Size2& p_new_size);
|
||||||
|
|
||||||
void grow_mask(int p_pixels, const Rect2 &p_rect);
|
void grow_mask(int p_pixels, const Rect2 &p_rect);
|
||||||
|
|
||||||
|
void blit(const Vector2& p_pos,const Ref<BitMap>& p_bitmap);
|
||||||
|
Ref<Image> convert_to_image() const;
|
||||||
|
|
||||||
Vector<Vector<Vector2> > clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const;
|
Vector<Vector<Vector2> > clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon = 2.0) const;
|
||||||
|
|
||||||
BitMap();
|
BitMap();
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "core/io/image_loader.h"
|
#include "core/io/image_loader.h"
|
||||||
#include "core/method_bind_ext.gen.inc"
|
#include "core/method_bind_ext.gen.inc"
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
|
#include "mesh.h"
|
||||||
#include "scene/resources/bit_map.h"
|
#include "scene/resources/bit_map.h"
|
||||||
|
|
||||||
Size2 Texture::get_size() const {
|
Size2 Texture::get_size() const {
|
||||||
|
@ -1133,6 +1134,138 @@ AtlasTexture::AtlasTexture() {
|
||||||
filter_clip = false;
|
filter_clip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
int MeshTexture::get_width() const {
|
||||||
|
return size.width;
|
||||||
|
}
|
||||||
|
int MeshTexture::get_height() const {
|
||||||
|
return size.height;
|
||||||
|
}
|
||||||
|
RID MeshTexture::get_rid() const {
|
||||||
|
return RID();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshTexture::has_alpha() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshTexture::set_flags(uint32_t p_flags) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MeshTexture::get_flags() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshTexture::set_mesh(const Ref<Mesh> &p_mesh) {
|
||||||
|
mesh = p_mesh;
|
||||||
|
}
|
||||||
|
Ref<Mesh> MeshTexture::get_mesh() const {
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshTexture::set_image_size(const Size2 &p_size) {
|
||||||
|
size = p_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2 MeshTexture::get_image_size() const {
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshTexture::set_base_texture(const Ref<Texture> &p_texture) {
|
||||||
|
base_texture = p_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Texture> MeshTexture::get_base_texture() const {
|
||||||
|
return base_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
|
||||||
|
|
||||||
|
if (mesh.is_null() || base_texture.is_null()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Transform2D xform;
|
||||||
|
xform.set_origin(p_pos);
|
||||||
|
if (p_transpose) {
|
||||||
|
SWAP(xform.elements[0][1], xform.elements[1][0]);
|
||||||
|
SWAP(xform.elements[0][0], xform.elements[1][1]);
|
||||||
|
}
|
||||||
|
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
|
||||||
|
VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
|
||||||
|
}
|
||||||
|
void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
|
||||||
|
if (mesh.is_null() || base_texture.is_null()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Transform2D xform;
|
||||||
|
Vector2 origin = p_rect.position;
|
||||||
|
if (p_rect.size.x < 0) {
|
||||||
|
origin.x += size.x;
|
||||||
|
}
|
||||||
|
if (p_rect.size.y < 0) {
|
||||||
|
origin.y += size.y;
|
||||||
|
}
|
||||||
|
xform.set_origin(origin);
|
||||||
|
xform.set_scale(p_rect.size / size);
|
||||||
|
|
||||||
|
if (p_transpose) {
|
||||||
|
SWAP(xform.elements[0][1], xform.elements[1][0]);
|
||||||
|
SWAP(xform.elements[0][0], xform.elements[1][1]);
|
||||||
|
}
|
||||||
|
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
|
||||||
|
VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
|
||||||
|
}
|
||||||
|
void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
|
||||||
|
|
||||||
|
if (mesh.is_null() || base_texture.is_null()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Transform2D xform;
|
||||||
|
Vector2 origin = p_rect.position;
|
||||||
|
if (p_rect.size.x < 0) {
|
||||||
|
origin.x += size.x;
|
||||||
|
}
|
||||||
|
if (p_rect.size.y < 0) {
|
||||||
|
origin.y += size.y;
|
||||||
|
}
|
||||||
|
xform.set_origin(origin);
|
||||||
|
xform.set_scale(p_rect.size / size);
|
||||||
|
|
||||||
|
if (p_transpose) {
|
||||||
|
SWAP(xform.elements[0][1], xform.elements[1][0]);
|
||||||
|
SWAP(xform.elements[0][0], xform.elements[1][1]);
|
||||||
|
}
|
||||||
|
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
|
||||||
|
VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid);
|
||||||
|
}
|
||||||
|
bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
|
||||||
|
r_rect = p_rect;
|
||||||
|
r_src_rect = p_src_rect;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshTexture::is_pixel_opaque(int p_x, int p_y) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshTexture::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshTexture::set_mesh);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_mesh"), &MeshTexture::get_mesh);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_image_size", "size"), &MeshTexture::set_image_size);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_image_size"), &MeshTexture::get_image_size);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_base_texture", "texture"), &MeshTexture::set_base_texture);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_base_texture"), &MeshTexture::get_base_texture);
|
||||||
|
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base_texture", "get_base_texture");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "image_size", PROPERTY_HINT_RANGE, "0,16384,1"), "set_image_size", "get_image_size");
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshTexture::MeshTexture() {
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
|
|
||||||
int LargeTexture::get_width() const {
|
int LargeTexture::get_width() const {
|
||||||
|
|
|
@ -293,6 +293,49 @@ public:
|
||||||
AtlasTexture();
|
AtlasTexture();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Mesh;
|
||||||
|
|
||||||
|
class MeshTexture : public Texture {
|
||||||
|
|
||||||
|
GDCLASS(MeshTexture, Texture);
|
||||||
|
RES_BASE_EXTENSION("meshtex");
|
||||||
|
|
||||||
|
Ref<Texture> base_texture;
|
||||||
|
Ref<Mesh> mesh;
|
||||||
|
Size2i size;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int get_width() const;
|
||||||
|
virtual int get_height() const;
|
||||||
|
virtual RID get_rid() const;
|
||||||
|
|
||||||
|
virtual bool has_alpha() const;
|
||||||
|
|
||||||
|
virtual void set_flags(uint32_t p_flags);
|
||||||
|
virtual uint32_t get_flags() const;
|
||||||
|
|
||||||
|
void set_mesh(const Ref<Mesh> &p_mesh);
|
||||||
|
Ref<Mesh> get_mesh() const;
|
||||||
|
|
||||||
|
void set_image_size(const Size2 &p_size);
|
||||||
|
Size2 get_image_size() const;
|
||||||
|
|
||||||
|
void set_base_texture(const Ref<Texture> &p_texture);
|
||||||
|
Ref<Texture> get_base_texture() const;
|
||||||
|
|
||||||
|
virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
|
||||||
|
virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
|
||||||
|
virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
|
||||||
|
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
|
||||||
|
|
||||||
|
bool is_pixel_opaque(int p_x, int p_y) const;
|
||||||
|
|
||||||
|
MeshTexture();
|
||||||
|
};
|
||||||
|
|
||||||
class LargeTexture : public Texture {
|
class LargeTexture : public Texture {
|
||||||
|
|
||||||
GDCLASS(LargeTexture, Texture);
|
GDCLASS(LargeTexture, Texture);
|
||||||
|
|
|
@ -789,6 +789,8 @@ public:
|
||||||
RID mesh;
|
RID mesh;
|
||||||
RID texture;
|
RID texture;
|
||||||
RID normal_map;
|
RID normal_map;
|
||||||
|
Transform2D transform;
|
||||||
|
Color modulate;
|
||||||
CommandMesh() { type = TYPE_MESH; }
|
CommandMesh() { type = TYPE_MESH; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -829,7 +829,7 @@ void VisualServerCanvas::canvas_item_add_set_transform(RID p_item, const Transfo
|
||||||
canvas_item->commands.push_back(tr);
|
canvas_item->commands.push_back(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture, RID p_normal_map) {
|
void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture, RID p_normal_map) {
|
||||||
|
|
||||||
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
||||||
ERR_FAIL_COND(!canvas_item);
|
ERR_FAIL_COND(!canvas_item);
|
||||||
|
@ -839,6 +839,8 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID
|
||||||
m->mesh = p_mesh;
|
m->mesh = p_mesh;
|
||||||
m->texture = p_texture;
|
m->texture = p_texture;
|
||||||
m->normal_map = p_normal_map;
|
m->normal_map = p_normal_map;
|
||||||
|
m->transform = p_transform;
|
||||||
|
m->modulate = p_modulate;
|
||||||
|
|
||||||
canvas_item->commands.push_back(m);
|
canvas_item->commands.push_back(m);
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ public:
|
||||||
void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID());
|
void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID());
|
||||||
void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false);
|
void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false);
|
||||||
void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
|
void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
|
||||||
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
|
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID(), RID p_normal_map = RID());
|
||||||
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
|
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
|
||||||
void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal);
|
void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal);
|
||||||
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
|
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
|
||||||
|
|
|
@ -600,7 +600,7 @@ public:
|
||||||
BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
|
BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
|
||||||
BIND7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
|
BIND7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
|
||||||
BIND10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
|
BIND10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
|
||||||
BIND4(canvas_item_add_mesh, RID, const RID &, RID, RID)
|
BIND6(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID)
|
||||||
BIND4(canvas_item_add_multimesh, RID, RID, RID, RID)
|
BIND4(canvas_item_add_multimesh, RID, RID, RID, RID)
|
||||||
BIND4(canvas_item_add_particles, RID, RID, RID, RID)
|
BIND4(canvas_item_add_particles, RID, RID, RID, RID)
|
||||||
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
|
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
|
||||||
|
|
|
@ -518,7 +518,7 @@ public:
|
||||||
FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
|
FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
|
||||||
FUNC7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
|
FUNC7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
|
||||||
FUNC10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
|
FUNC10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
|
||||||
FUNC4(canvas_item_add_mesh, RID, const RID &, RID, RID)
|
FUNC6(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID)
|
||||||
FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID)
|
FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID)
|
||||||
FUNC4(canvas_item_add_particles, RID, RID, RID, RID)
|
FUNC4(canvas_item_add_particles, RID, RID, RID, RID)
|
||||||
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
|
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
|
||||||
|
|
|
@ -898,7 +898,7 @@ public:
|
||||||
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0;
|
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0;
|
||||||
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false) = 0;
|
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false) = 0;
|
||||||
virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
|
virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
|
||||||
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
|
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID(), RID p_normal_map = RID()) = 0;
|
||||||
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
|
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
|
||||||
virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map) = 0;
|
virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map) = 0;
|
||||||
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
|
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
|
||||||
|
|
Loading…
Reference in a new issue