summaryrefslogtreecommitdiff
path: root/scene/2d/polygon_2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d/polygon_2d.cpp')
-rw-r--r--scene/2d/polygon_2d.cpp236
1 files changed, 85 insertions, 151 deletions
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 84c1828b47..7366be5a7d 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,7 @@
#include "polygon_2d.h"
-#include "core/math/geometry.h"
+#include "core/math/geometry_2d.h"
#include "skeleton_2d.h"
#ifdef TOOLS_ENABLED
@@ -65,10 +65,11 @@ Rect2 Polygon2D::_edit_get_rect() const {
item_rect = Rect2();
for (int i = 0; i < l; i++) {
Vector2 pos = r[i] + offset;
- if (i == 0)
+ if (i == 0) {
item_rect.position = pos;
- else
+ } else {
item_rect.expand_to(pos);
+ }
}
rect_cache_dirty = false;
}
@@ -81,27 +82,30 @@ bool Polygon2D::_edit_use_rect() const {
}
bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
Vector<Vector2> polygon2d = Variant(polygon);
if (internal_vertices > 0) {
polygon2d.resize(polygon2d.size() - internal_vertices);
}
- return Geometry::is_point_in_polygon(p_point - get_offset(), polygon2d);
+ return Geometry2D::is_point_in_polygon(p_point - get_offset(), polygon2d);
}
#endif
+void Polygon2D::_validate_property(PropertyInfo &property) const {
+ if (!invert && property.name == "invert_border") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Polygon2D::_skeleton_bone_setup_changed() {
update();
}
void Polygon2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
- if (polygon.size() < 3)
+ if (polygon.size() < 3) {
return;
+ }
Skeleton2D *skeleton_node = nullptr;
if (has_node(skeleton)) {
@@ -147,7 +151,6 @@ void Polygon2D::_notification(int p_what) {
points.resize(len);
{
-
const Vector2 *polyr = polygon.ptr();
for (int i = 0; i < len; i++) {
points.write[i] = polyr[i] + offset;
@@ -155,17 +158,17 @@ void Polygon2D::_notification(int p_what) {
}
if (invert) {
-
Rect2 bounds;
int highest_idx = -1;
- float highest_y = -1e20;
- float sum = 0;
+ real_t highest_y = -1e20;
+ real_t sum = 0.0;
for (int i = 0; i < len; i++) {
- if (i == 0)
+ if (i == 0) {
bounds.position = points[i];
- else
+ } else {
bounds.expand_to(points[i]);
+ }
if (points[i].y > highest_y) {
highest_idx = i;
highest_y = points[i].y;
@@ -195,12 +198,10 @@ void Polygon2D::_notification(int p_what) {
points.resize(points.size() + 7);
for (int i = points.size() - 1; i >= highest_idx + 7; i--) {
-
points.write[i] = points[i - 7];
}
for (int i = 0; i < 7; i++) {
-
points.write[highest_idx + i + 1] = ep[i];
}
@@ -208,7 +209,6 @@ void Polygon2D::_notification(int p_what) {
}
if (texture.is_valid()) {
-
Transform2D texmat(tex_rot, tex_ofs);
texmat.scale(tex_scale);
Size2 tex_size = texture->get_size();
@@ -216,7 +216,6 @@ void Polygon2D::_notification(int p_what) {
uvs.resize(len);
if (points.size() == uv.size()) {
-
const Vector2 *uvr = uv.ptr();
for (int i = 0; i < len; i++) {
@@ -259,8 +258,9 @@ void Polygon2D::_notification(int p_what) {
int bone_index = bone->get_index_in_skeleton();
const float *r = bone_weights[i].weights.ptr();
for (int j = 0; j < vc; j++) {
- if (r[j] == 0.0)
+ if (r[j] == 0.0) {
continue; //weight is unpainted, skip
+ }
//find an index with a weight
for (int k = 0; k < 4; k++) {
if (weightsw[j * 4 + k] < r[j]) {
@@ -279,12 +279,13 @@ void Polygon2D::_notification(int p_what) {
//normalize the weights
for (int i = 0; i < vc; i++) {
- float tw = 0;
+ real_t tw = 0.0;
for (int j = 0; j < 4; j++) {
tw += weightsw[i * 4 + j];
}
- if (tw == 0)
+ if (tw == 0) {
continue; //unpainted, do nothing
+ }
//normalize
for (int j = 0; j < 4; j++) {
@@ -301,22 +302,24 @@ void Polygon2D::_notification(int p_what) {
colors.write[i] = color_r[i];
}
} else {
- colors.push_back(color);
+ colors.resize(len);
+ for (int i = 0; i < len; i++) {
+ colors.write[i] = color;
+ }
}
+ Vector<int> index_array;
+
if (invert || polygons.size() == 0) {
- Vector<int> indices = Geometry::triangulate_polygon(points);
- if (indices.size()) {
- RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, normal_map.is_valid() ? normal_map->get_rid() : RID(), specular_map.is_valid() ? specular_map->get_rid() : RID(), Color(specular_color.r, specular_color.g, specular_color.b, shininess));
- }
+ index_array = Geometry2D::triangulate_polygon(points);
} else {
//draw individual polygons
- Vector<int> total_indices;
for (int i = 0; i < polygons.size(); i++) {
Vector<int> src_indices = polygons[i];
int ic = src_indices.size();
- if (ic < 3)
+ if (ic < 3) {
continue;
+ }
const int *r = src_indices.ptr();
Vector<Vector2> tmp_points;
@@ -327,22 +330,42 @@ void Polygon2D::_notification(int p_what) {
ERR_CONTINUE(idx < 0 || idx >= points.size());
tmp_points.write[j] = points[r[j]];
}
- Vector<int> indices = Geometry::triangulate_polygon(tmp_points);
+ Vector<int> indices = Geometry2D::triangulate_polygon(tmp_points);
int ic2 = indices.size();
const int *r2 = indices.ptr();
- int bic = total_indices.size();
- total_indices.resize(bic + ic2);
- int *w2 = total_indices.ptrw();
+ int bic = index_array.size();
+ index_array.resize(bic + ic2);
+ int *w2 = index_array.ptrw();
for (int j = 0; j < ic2; j++) {
w2[j + bic] = r[r2[j]];
}
}
+ }
+
+ RS::get_singleton()->mesh_clear(mesh);
+
+ if (index_array.size()) {
+ Array arr;
+ arr.resize(RS::ARRAY_MAX);
+ arr[RS::ARRAY_VERTEX] = points;
+ if (uvs.size() == points.size()) {
+ arr[RS::ARRAY_TEX_UV] = uvs;
+ }
+ if (colors.size() == points.size()) {
+ arr[RS::ARRAY_COLOR] = colors;
+ }
- if (total_indices.size()) {
- RS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID());
+ if (bones.size() == points.size() * 4) {
+ arr[RS::ARRAY_BONES] = bones;
+ arr[RS::ARRAY_WEIGHTS] = weights;
}
+
+ arr[RS::ARRAY_INDEX] = index_array;
+
+ RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES);
+ RS::get_singleton()->canvas_item_add_mesh(get_canvas_item(), mesh, Transform2D(), Color(1, 1, 1), texture.is_valid() ? texture->get_rid() : RID());
}
} break;
@@ -356,12 +379,10 @@ void Polygon2D::set_polygon(const Vector<Vector2> &p_polygon) {
}
Vector<Vector2> Polygon2D::get_polygon() const {
-
return polygon;
}
void Polygon2D::set_internal_vertex_count(int p_count) {
-
internal_vertices = p_count;
}
@@ -370,49 +391,42 @@ int Polygon2D::get_internal_vertex_count() const {
}
void Polygon2D::set_uv(const Vector<Vector2> &p_uv) {
-
uv = p_uv;
update();
}
Vector<Vector2> Polygon2D::get_uv() const {
-
return uv;
}
void Polygon2D::set_polygons(const Array &p_polygons) {
-
polygons = p_polygons;
update();
}
Array Polygon2D::get_polygons() const {
-
return polygons;
}
void Polygon2D::set_color(const Color &p_color) {
-
color = p_color;
update();
}
-Color Polygon2D::get_color() const {
+Color Polygon2D::get_color() const {
return color;
}
void Polygon2D::set_vertex_colors(const Vector<Color> &p_colors) {
-
vertex_colors = p_colors;
update();
}
-Vector<Color> Polygon2D::get_vertex_colors() const {
+Vector<Color> Polygon2D::get_vertex_colors() const {
return vertex_colors;
}
void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) {
-
texture = p_texture;
/*if (texture.is_valid()) {
@@ -425,150 +439,98 @@ void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) {
}*/
update();
}
-Ref<Texture2D> Polygon2D::get_texture() const {
+Ref<Texture2D> Polygon2D::get_texture() const {
return texture;
}
-void Polygon2D::set_normal_map(const Ref<Texture2D> &p_normal_map) {
- normal_map = p_normal_map;
- update();
-}
-
-Ref<Texture2D> Polygon2D::get_normal_map() const {
- return normal_map;
-}
-
-void Polygon2D::set_specular_map(const Ref<Texture2D> &p_specular_map) {
- specular_map = p_specular_map;
- update();
-}
-
-Ref<Texture2D> Polygon2D::get_specular_map() const {
- return specular_map;
-}
-
-void Polygon2D::set_specular_color(const Color &p_specular_color) {
- specular_color = p_specular_color;
- update();
-}
-
-Color Polygon2D::get_specular_color() const {
- return specular_color;
-}
-
-void Polygon2D::set_shininess(float p_shininess) {
- shininess = CLAMP(p_shininess, 0.0, 1.0);
- update();
-}
-
-float Polygon2D::get_shininess() const {
- return shininess;
-}
-
void Polygon2D::set_texture_offset(const Vector2 &p_offset) {
-
tex_ofs = p_offset;
update();
}
-Vector2 Polygon2D::get_texture_offset() const {
+Vector2 Polygon2D::get_texture_offset() const {
return tex_ofs;
}
-void Polygon2D::set_texture_rotation(float p_rot) {
-
+void Polygon2D::set_texture_rotation(real_t p_rot) {
tex_rot = p_rot;
update();
}
-float Polygon2D::get_texture_rotation() const {
+real_t Polygon2D::get_texture_rotation() const {
return tex_rot;
}
-void Polygon2D::set_texture_rotation_degrees(float p_rot) {
-
- set_texture_rotation(Math::deg2rad(p_rot));
-}
-float Polygon2D::get_texture_rotation_degrees() const {
-
- return Math::rad2deg(get_texture_rotation());
-}
-
void Polygon2D::set_texture_scale(const Size2 &p_scale) {
-
tex_scale = p_scale;
update();
}
-Size2 Polygon2D::get_texture_scale() const {
+Size2 Polygon2D::get_texture_scale() const {
return tex_scale;
}
void Polygon2D::set_invert(bool p_invert) {
-
invert = p_invert;
update();
+ notify_property_list_changed();
}
-bool Polygon2D::get_invert() const {
+bool Polygon2D::get_invert() const {
return invert;
}
void Polygon2D::set_antialiased(bool p_antialiased) {
-
antialiased = p_antialiased;
update();
}
-bool Polygon2D::get_antialiased() const {
+bool Polygon2D::get_antialiased() const {
return antialiased;
}
-void Polygon2D::set_invert_border(float p_invert_border) {
-
+void Polygon2D::set_invert_border(real_t p_invert_border) {
invert_border = p_invert_border;
update();
}
-float Polygon2D::get_invert_border() const {
+real_t Polygon2D::get_invert_border() const {
return invert_border;
}
void Polygon2D::set_offset(const Vector2 &p_offset) {
-
offset = p_offset;
rect_cache_dirty = true;
update();
- _change_notify("offset");
}
Vector2 Polygon2D::get_offset() const {
-
return offset;
}
void Polygon2D::add_bone(const NodePath &p_path, const Vector<float> &p_weights) {
-
Bone bone;
bone.path = p_path;
bone.weights = p_weights;
bone_weights.push_back(bone);
}
+
int Polygon2D::get_bone_count() const {
return bone_weights.size();
}
+
NodePath Polygon2D::get_bone_path(int p_index) const {
ERR_FAIL_INDEX_V(p_index, bone_weights.size(), NodePath());
return bone_weights[p_index].path;
}
-Vector<float> Polygon2D::get_bone_weights(int p_index) const {
+Vector<float> Polygon2D::get_bone_weights(int p_index) const {
ERR_FAIL_INDEX_V(p_index, bone_weights.size(), Vector<float>());
return bone_weights[p_index].weights;
}
-void Polygon2D::erase_bone(int p_idx) {
+void Polygon2D::erase_bone(int p_idx) {
ERR_FAIL_INDEX(p_idx, bone_weights.size());
bone_weights.remove(p_idx);
}
@@ -582,6 +544,7 @@ void Polygon2D::set_bone_weights(int p_index, const Vector<float> &p_weights) {
bone_weights.write[p_index].weights = p_weights;
update();
}
+
void Polygon2D::set_bone_path(int p_index, const NodePath &p_path) {
ERR_FAIL_INDEX(p_index, bone_weights.size());
bone_weights.write[p_index].path = p_path;
@@ -596,8 +559,8 @@ Array Polygon2D::_get_bones() const {
}
return bones;
}
-void Polygon2D::_set_bones(const Array &p_bones) {
+void Polygon2D::_set_bones(const Array &p_bones) {
ERR_FAIL_COND(p_bones.size() & 1);
clear_bones();
for (int i = 0; i < p_bones.size(); i += 2) {
@@ -606,8 +569,9 @@ void Polygon2D::_set_bones(const Array &p_bones) {
}
void Polygon2D::set_skeleton(const NodePath &p_skeleton) {
- if (skeleton == p_skeleton)
+ if (skeleton == p_skeleton) {
return;
+ }
skeleton = p_skeleton;
update();
}
@@ -617,7 +581,6 @@ NodePath Polygon2D::get_skeleton() const {
}
void Polygon2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &Polygon2D::set_polygon);
ClassDB::bind_method(D_METHOD("get_polygon"), &Polygon2D::get_polygon);
@@ -636,27 +599,12 @@ void Polygon2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Polygon2D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &Polygon2D::get_texture);
- ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &Polygon2D::set_normal_map);
- ClassDB::bind_method(D_METHOD("get_normal_map"), &Polygon2D::get_normal_map);
-
- ClassDB::bind_method(D_METHOD("set_specular_map", "specular_map"), &Polygon2D::set_specular_map);
- ClassDB::bind_method(D_METHOD("get_specular_map"), &Polygon2D::get_specular_map);
-
- ClassDB::bind_method(D_METHOD("set_specular_color", "specular_color"), &Polygon2D::set_specular_color);
- ClassDB::bind_method(D_METHOD("get_specular_color"), &Polygon2D::get_specular_color);
-
- ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &Polygon2D::set_shininess);
- ClassDB::bind_method(D_METHOD("get_shininess"), &Polygon2D::get_shininess);
-
ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Polygon2D::set_texture_offset);
ClassDB::bind_method(D_METHOD("get_texture_offset"), &Polygon2D::get_texture_offset);
ClassDB::bind_method(D_METHOD("set_texture_rotation", "texture_rotation"), &Polygon2D::set_texture_rotation);
ClassDB::bind_method(D_METHOD("get_texture_rotation"), &Polygon2D::get_texture_rotation);
- ClassDB::bind_method(D_METHOD("set_texture_rotation_degrees", "texture_rotation"), &Polygon2D::set_texture_rotation_degrees);
- ClassDB::bind_method(D_METHOD("get_texture_rotation_degrees"), &Polygon2D::get_texture_rotation_degrees);
-
ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &Polygon2D::set_texture_scale);
ClassDB::bind_method(D_METHOD("get_texture_scale"), &Polygon2D::get_texture_scale);
@@ -698,13 +646,7 @@ void Polygon2D::_bind_methods() {
ADD_GROUP("Texture2D", "texture_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_offset"), "set_texture_offset", "get_texture_offset");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale"), "set_texture_scale", "get_texture_scale");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_texture_rotation_degrees", "get_texture_rotation_degrees");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation");
- ADD_GROUP("Lighting", "");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "specular_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_specular_map", "get_specular_map");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_texture_rotation", "get_texture_rotation");
ADD_GROUP("Skeleton", "");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton");
@@ -722,17 +664,9 @@ void Polygon2D::_bind_methods() {
}
Polygon2D::Polygon2D() {
+ mesh = RS::get_singleton()->mesh_create();
+}
- invert = 0;
- invert_border = 100;
- antialiased = false;
- tex_rot = 0;
- tex_tile = true;
- tex_scale = Vector2(1, 1);
- color = Color(1, 1, 1);
- rect_cache_dirty = true;
- internal_vertices = 0;
-
- specular_color = Color(1, 1, 1, 1);
- shininess = 1.0;
+Polygon2D::~Polygon2D() {
+ RS::get_singleton()->free(mesh);
}