You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-17 14:11:06 +00:00
Move tile transforms handling cache to TileData
This commit is contained in:
@@ -70,15 +70,23 @@
|
|||||||
<method name="get_navigation_polygon" qualifiers="const">
|
<method name="get_navigation_polygon" qualifiers="const">
|
||||||
<return type="NavigationPolygon" />
|
<return type="NavigationPolygon" />
|
||||||
<param index="0" name="layer_id" type="int" />
|
<param index="0" name="layer_id" type="int" />
|
||||||
|
<param index="1" name="flip_h" type="bool" default="false" />
|
||||||
|
<param index="2" name="flip_v" type="bool" default="false" />
|
||||||
|
<param index="3" name="transpose" type="bool" default="false" />
|
||||||
<description>
|
<description>
|
||||||
Returns the navigation polygon of the tile for the TileSet navigation layer with index [param layer_id].
|
Returns the navigation polygon of the tile for the TileSet navigation layer with index [param layer_id].
|
||||||
|
[param flip_h], [param flip_v], and [param transpose] allow transforming the returned polygon.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_occluder" qualifiers="const">
|
<method name="get_occluder" qualifiers="const">
|
||||||
<return type="OccluderPolygon2D" />
|
<return type="OccluderPolygon2D" />
|
||||||
<param index="0" name="layer_id" type="int" />
|
<param index="0" name="layer_id" type="int" />
|
||||||
|
<param index="1" name="flip_h" type="bool" default="false" />
|
||||||
|
<param index="2" name="flip_v" type="bool" default="false" />
|
||||||
|
<param index="3" name="transpose" type="bool" default="false" />
|
||||||
<description>
|
<description>
|
||||||
Returns the occluder polygon of the tile for the TileSet occlusion layer with index [param layer_id].
|
Returns the occluder polygon of the tile for the TileSet occlusion layer with index [param layer_id].
|
||||||
|
[param flip_h], [param flip_v], and [param transpose] allow transforming the returned polygon.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_terrain_peering_bit" qualifiers="const">
|
<method name="get_terrain_peering_bit" qualifiers="const">
|
||||||
|
|||||||
@@ -1421,8 +1421,8 @@ void TileDataOcclusionShapeEditor::draw_over_tile(CanvasItem *p_canvas_item, Tra
|
|||||||
|
|
||||||
Variant TileDataOcclusionShapeEditor::_get_painted_value() {
|
Variant TileDataOcclusionShapeEditor::_get_painted_value() {
|
||||||
Ref<OccluderPolygon2D> occluder_polygon;
|
Ref<OccluderPolygon2D> occluder_polygon;
|
||||||
occluder_polygon.instantiate();
|
|
||||||
if (polygon_editor->get_polygon_count() >= 1) {
|
if (polygon_editor->get_polygon_count() >= 1) {
|
||||||
|
occluder_polygon.instantiate();
|
||||||
occluder_polygon->set_polygon(polygon_editor->get_polygon(0));
|
occluder_polygon->set_polygon(polygon_editor->get_polygon(0));
|
||||||
}
|
}
|
||||||
return occluder_polygon;
|
return occluder_polygon;
|
||||||
|
|||||||
@@ -7,3 +7,10 @@ should instead be used to justify these changes and describe how users should wo
|
|||||||
Add new entries at the end of the file.
|
Add new entries at the end of the file.
|
||||||
|
|
||||||
## Changes between 4.2-stable and 4.3-stable
|
## Changes between 4.2-stable and 4.3-stable
|
||||||
|
|
||||||
|
GH-84660
|
||||||
|
--------
|
||||||
|
Validate extension JSON: Error: Field 'classes/TileData/methods/get_navigation_polygon/arguments': size changed value in new API, from 1 to 4.
|
||||||
|
Validate extension JSON: Error: Field 'classes/TileData/methods/get_occluder/arguments': size changed value in new API, from 1 to 4.
|
||||||
|
|
||||||
|
Added optional argument to get_navigation_polygon and get_occluder to specify a polygon transform.
|
||||||
|
|||||||
@@ -591,13 +591,19 @@ void NavMeshGenerator2D::generator_parse_tilemap_node(const Ref<NavigationPolygo
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform flags.
|
||||||
|
const int alternative_id = tilemap->get_cell_alternative_tile(tilemap_layer, cell, false);
|
||||||
|
bool flip_h = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_H);
|
||||||
|
bool flip_v = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_V);
|
||||||
|
bool transpose = (alternative_id & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
|
||||||
|
|
||||||
Transform2D tile_transform;
|
Transform2D tile_transform;
|
||||||
tile_transform.set_origin(tilemap->map_to_local(cell));
|
tile_transform.set_origin(tilemap->map_to_local(cell));
|
||||||
|
|
||||||
const Transform2D tile_transform_offset = tilemap_xform * tile_transform;
|
const Transform2D tile_transform_offset = tilemap_xform * tile_transform;
|
||||||
|
|
||||||
if (navigation_layers_count > 0) {
|
if (navigation_layers_count > 0) {
|
||||||
Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(tilemap_layer);
|
Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(tilemap_layer, flip_h, flip_v, transpose);
|
||||||
if (navigation_polygon.is_valid()) {
|
if (navigation_polygon.is_valid()) {
|
||||||
for (int outline_index = 0; outline_index < navigation_polygon->get_outline_count(); outline_index++) {
|
for (int outline_index = 0; outline_index < navigation_polygon->get_outline_count(); outline_index++) {
|
||||||
const Vector<Vector2> &navigation_polygon_outline = navigation_polygon->get_outline(outline_index);
|
const Vector<Vector2> &navigation_polygon_outline = navigation_polygon->get_outline(outline_index);
|
||||||
@@ -622,11 +628,15 @@ void NavMeshGenerator2D::generator_parse_tilemap_node(const Ref<NavigationPolygo
|
|||||||
|
|
||||||
if (physics_layers_count > 0 && (parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS || parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_BOTH) && (tile_set->get_physics_layer_collision_layer(tilemap_layer) & parsed_collision_mask)) {
|
if (physics_layers_count > 0 && (parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS || parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_BOTH) && (tile_set->get_physics_layer_collision_layer(tilemap_layer) & parsed_collision_mask)) {
|
||||||
for (int collision_polygon_index = 0; collision_polygon_index < tile_data->get_collision_polygons_count(tilemap_layer); collision_polygon_index++) {
|
for (int collision_polygon_index = 0; collision_polygon_index < tile_data->get_collision_polygons_count(tilemap_layer); collision_polygon_index++) {
|
||||||
const Vector<Vector2> &collision_polygon_points = tile_data->get_collision_polygon_points(tilemap_layer, collision_polygon_index);
|
PackedVector2Array collision_polygon_points = tile_data->get_collision_polygon_points(tilemap_layer, collision_polygon_index);
|
||||||
if (collision_polygon_points.size() == 0) {
|
if (collision_polygon_points.size() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flip_h || flip_v || transpose) {
|
||||||
|
collision_polygon_points = TileData::get_transformed_vertices(collision_polygon_points, flip_h, flip_v, transpose);
|
||||||
|
}
|
||||||
|
|
||||||
Vector<Vector2> obstruction_outline;
|
Vector<Vector2> obstruction_outline;
|
||||||
obstruction_outline.resize(collision_polygon_points.size());
|
obstruction_outline.resize(collision_polygon_points.size());
|
||||||
|
|
||||||
|
|||||||
@@ -447,11 +447,12 @@ void TileMapLayer::_rendering_update() {
|
|||||||
for (KeyValue<Vector2i, CellData> &kv : tile_map) {
|
for (KeyValue<Vector2i, CellData> &kv : tile_map) {
|
||||||
CellData &cell_data = kv.value;
|
CellData &cell_data = kv.value;
|
||||||
for (const RID &occluder : cell_data.occluders) {
|
for (const RID &occluder : cell_data.occluders) {
|
||||||
if (occluder.is_valid()) {
|
if (occluder.is_null()) {
|
||||||
Transform2D xform(0, tile_map_node->map_to_local(kv.key));
|
continue;
|
||||||
rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas());
|
|
||||||
rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform);
|
|
||||||
}
|
}
|
||||||
|
Transform2D xform(0, tile_map_node->map_to_local(kv.key));
|
||||||
|
rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas());
|
||||||
|
rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -591,6 +592,11 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) {
|
|||||||
tile_data = atlas_source->get_tile_data(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile);
|
tile_data = atlas_source->get_tile_data(r_cell_data.cell.get_atlas_coords(), r_cell_data.cell.alternative_tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform flags.
|
||||||
|
bool flip_h = (r_cell_data.cell.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H);
|
||||||
|
bool flip_v = (r_cell_data.cell.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V);
|
||||||
|
bool transpose = (r_cell_data.cell.alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
|
||||||
|
|
||||||
// Create, update or clear occluders.
|
// Create, update or clear occluders.
|
||||||
for (uint32_t occlusion_layer_index = 0; occlusion_layer_index < r_cell_data.occluders.size(); occlusion_layer_index++) {
|
for (uint32_t occlusion_layer_index = 0; occlusion_layer_index < r_cell_data.occluders.size(); occlusion_layer_index++) {
|
||||||
Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder(occlusion_layer_index);
|
Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder(occlusion_layer_index);
|
||||||
@@ -606,7 +612,7 @@ void TileMapLayer::_rendering_occluders_update_cell(CellData &r_cell_data) {
|
|||||||
}
|
}
|
||||||
rs->canvas_light_occluder_set_enabled(occluder, node_visible);
|
rs->canvas_light_occluder_set_enabled(occluder, node_visible);
|
||||||
rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform);
|
rs->canvas_light_occluder_set_transform(occluder, tile_map_node->get_global_transform() * xform);
|
||||||
rs->canvas_light_occluder_set_polygon(occluder, tile_map_node->get_transformed_polygon(Ref<Resource>(tile_data->get_occluder(occlusion_layer_index)), r_cell_data.cell.alternative_tile)->get_rid());
|
rs->canvas_light_occluder_set_polygon(occluder, tile_data->get_occluder(occlusion_layer_index, flip_h, flip_v, transpose)->get_rid());
|
||||||
rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas());
|
rs->canvas_light_occluder_attach_to_canvas(occluder, tile_map_node->get_canvas());
|
||||||
rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index));
|
rs->canvas_light_occluder_set_light_mask(occluder, tile_set->get_occlusion_layer_light_mask(occlusion_layer_index));
|
||||||
} else {
|
} else {
|
||||||
@@ -800,6 +806,11 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
|
|||||||
tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
|
tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform flags.
|
||||||
|
bool flip_h = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H);
|
||||||
|
bool flip_v = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V);
|
||||||
|
bool transpose = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
|
||||||
|
|
||||||
// Free unused bodies then resize the bodies array.
|
// Free unused bodies then resize the bodies array.
|
||||||
for (uint32_t i = tile_set->get_physics_layers_count(); i < r_cell_data.bodies.size(); i++) {
|
for (uint32_t i = tile_set->get_physics_layers_count(); i < r_cell_data.bodies.size(); i++) {
|
||||||
RID body = r_cell_data.bodies[i];
|
RID body = r_cell_data.bodies[i];
|
||||||
@@ -864,8 +875,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
|
|||||||
int shapes_count = tile_data->get_collision_polygon_shapes_count(tile_set_physics_layer, polygon_index);
|
int shapes_count = tile_data->get_collision_polygon_shapes_count(tile_set_physics_layer, polygon_index);
|
||||||
for (int shape_index = 0; shape_index < shapes_count; shape_index++) {
|
for (int shape_index = 0; shape_index < shapes_count; shape_index++) {
|
||||||
// Add decomposed convex shapes.
|
// Add decomposed convex shapes.
|
||||||
Ref<ConvexPolygonShape2D> shape = tile_data->get_collision_polygon_shape(tile_set_physics_layer, polygon_index, shape_index);
|
Ref<ConvexPolygonShape2D> shape = tile_data->get_collision_polygon_shape(tile_set_physics_layer, polygon_index, shape_index, flip_h, flip_v, transpose);
|
||||||
shape = tile_map_node->get_transformed_polygon(Ref<Resource>(shape), c.alternative_tile);
|
|
||||||
ps->body_add_shape(body, shape->get_rid());
|
ps->body_add_shape(body, shape->get_rid());
|
||||||
ps->body_set_shape_as_one_way_collision(body, body_shape_index, one_way_collision, one_way_collision_margin);
|
ps->body_set_shape_as_one_way_collision(body, body_shape_index, one_way_collision, one_way_collision_margin);
|
||||||
|
|
||||||
@@ -1053,6 +1063,11 @@ void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) {
|
|||||||
tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
|
tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform flags.
|
||||||
|
bool flip_h = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H);
|
||||||
|
bool flip_v = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V);
|
||||||
|
bool transpose = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
|
||||||
|
|
||||||
// Free unused regions then resize the regions array.
|
// Free unused regions then resize the regions array.
|
||||||
for (uint32_t i = tile_set->get_navigation_layers_count(); i < r_cell_data.navigation_regions.size(); i++) {
|
for (uint32_t i = tile_set->get_navigation_layers_count(); i < r_cell_data.navigation_regions.size(); i++) {
|
||||||
RID ®ion = r_cell_data.navigation_regions[i];
|
RID ®ion = r_cell_data.navigation_regions[i];
|
||||||
@@ -1066,9 +1081,7 @@ void TileMapLayer::_navigation_update_cell(CellData &r_cell_data) {
|
|||||||
|
|
||||||
// Create, update or clear regions.
|
// Create, update or clear regions.
|
||||||
for (uint32_t navigation_layer_index = 0; navigation_layer_index < r_cell_data.navigation_regions.size(); navigation_layer_index++) {
|
for (uint32_t navigation_layer_index = 0; navigation_layer_index < r_cell_data.navigation_regions.size(); navigation_layer_index++) {
|
||||||
Ref<NavigationPolygon> navigation_polygon;
|
Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(navigation_layer_index, flip_h, flip_v, transpose);
|
||||||
navigation_polygon = tile_data->get_navigation_polygon(navigation_layer_index);
|
|
||||||
navigation_polygon = tile_map_node->get_transformed_polygon(Ref<Resource>(navigation_polygon), c.alternative_tile);
|
|
||||||
|
|
||||||
RID ®ion = r_cell_data.navigation_regions[navigation_layer_index];
|
RID ®ion = r_cell_data.navigation_regions[navigation_layer_index];
|
||||||
|
|
||||||
@@ -1161,9 +1174,11 @@ void TileMapLayer::_navigation_draw_cell_debug(const RID &p_canvas_item, const V
|
|||||||
rs->canvas_item_add_set_transform(p_canvas_item, cell_to_quadrant);
|
rs->canvas_item_add_set_transform(p_canvas_item, cell_to_quadrant);
|
||||||
|
|
||||||
for (int layer_index = 0; layer_index < tile_set->get_navigation_layers_count(); layer_index++) {
|
for (int layer_index = 0; layer_index < tile_set->get_navigation_layers_count(); layer_index++) {
|
||||||
Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(layer_index);
|
bool flip_h = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_H);
|
||||||
|
bool flip_v = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_FLIP_V);
|
||||||
|
bool transpose = (c.alternative_tile & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
|
||||||
|
Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(layer_index, flip_h, flip_v, transpose);
|
||||||
if (navigation_polygon.is_valid()) {
|
if (navigation_polygon.is_valid()) {
|
||||||
navigation_polygon = tile_map_node->get_transformed_polygon(Ref<Resource>(navigation_polygon), c.alternative_tile);
|
|
||||||
Vector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices();
|
Vector<Vector2> navigation_polygon_vertices = navigation_polygon->get_vertices();
|
||||||
if (navigation_polygon_vertices.size() < 3) {
|
if (navigation_polygon_vertices.size() < 3) {
|
||||||
continue;
|
continue;
|
||||||
@@ -3119,11 +3134,6 @@ void TileMap::_internal_update() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This should only clear polygons that are no longer going to be used, but since it's difficult to determine,
|
|
||||||
// the cache is never cleared at runtime to prevent invalidating used polygons.
|
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
|
||||||
polygon_cache.clear();
|
|
||||||
}
|
|
||||||
// Update dirty quadrants on layers.
|
// Update dirty quadrants on layers.
|
||||||
for (Ref<TileMapLayer> &layer : layers) {
|
for (Ref<TileMapLayer> &layer : layers) {
|
||||||
layer->internal_update();
|
layer->internal_update();
|
||||||
@@ -3608,37 +3618,6 @@ Rect2 TileMap::_edit_get_rect() const {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PackedVector2Array TileMap::_get_transformed_vertices(const PackedVector2Array &p_vertices, int p_alternative_id) {
|
|
||||||
const Vector2 *r = p_vertices.ptr();
|
|
||||||
int size = p_vertices.size();
|
|
||||||
|
|
||||||
PackedVector2Array new_points;
|
|
||||||
new_points.resize(size);
|
|
||||||
Vector2 *w = new_points.ptrw();
|
|
||||||
|
|
||||||
bool flip_h = (p_alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_H);
|
|
||||||
bool flip_v = (p_alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_V);
|
|
||||||
bool transpose = (p_alternative_id & TileSetAtlasSource::TRANSFORM_TRANSPOSE);
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
Vector2 v;
|
|
||||||
if (transpose) {
|
|
||||||
v = Vector2(r[i].y, r[i].x);
|
|
||||||
} else {
|
|
||||||
v = r[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flip_h) {
|
|
||||||
v.x *= -1;
|
|
||||||
}
|
|
||||||
if (flip_v) {
|
|
||||||
v.y *= -1;
|
|
||||||
}
|
|
||||||
w[i] = v;
|
|
||||||
}
|
|
||||||
return new_points;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
|
bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
Vector<String> components = String(p_name).split("/", true, 2);
|
Vector<String> components = String(p_name).split("/", true, 2);
|
||||||
if (p_name == "format") {
|
if (p_name == "format") {
|
||||||
@@ -4637,57 +4616,6 @@ void TileMap::draw_cells_outline(Control *p_control, const RBSet<Vector2i> &p_ce
|
|||||||
#undef DRAW_SIDE_IF_NEEDED
|
#undef DRAW_SIDE_IF_NEEDED
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Resource> TileMap::get_transformed_polygon(Ref<Resource> p_polygon, int p_alternative_id) {
|
|
||||||
if (!bool(p_alternative_id & (TileSetAtlasSource::TRANSFORM_FLIP_H | TileSetAtlasSource::TRANSFORM_FLIP_V | TileSetAtlasSource::TRANSFORM_TRANSPOSE))) {
|
|
||||||
return p_polygon;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
HashMap<Pair<Ref<Resource>, int>, Ref<Resource>, PairHash<Ref<Resource>, int>>::Iterator E = polygon_cache.find(Pair<Ref<Resource>, int>(p_polygon, p_alternative_id));
|
|
||||||
if (E) {
|
|
||||||
return E->value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<ConvexPolygonShape2D> col = p_polygon;
|
|
||||||
if (col.is_valid()) {
|
|
||||||
Ref<ConvexPolygonShape2D> ret;
|
|
||||||
ret.instantiate();
|
|
||||||
ret->set_points(_get_transformed_vertices(col->get_points(), p_alternative_id));
|
|
||||||
polygon_cache[Pair<Ref<Resource>, int>(p_polygon, p_alternative_id)] = ret;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<NavigationPolygon> nav = p_polygon;
|
|
||||||
if (nav.is_valid()) {
|
|
||||||
PackedVector2Array new_points = _get_transformed_vertices(nav->get_vertices(), p_alternative_id);
|
|
||||||
Ref<NavigationPolygon> ret;
|
|
||||||
ret.instantiate();
|
|
||||||
ret->set_vertices(new_points);
|
|
||||||
|
|
||||||
PackedInt32Array indices;
|
|
||||||
indices.resize(new_points.size());
|
|
||||||
int *w = indices.ptrw();
|
|
||||||
for (int i = 0; i < new_points.size(); i++) {
|
|
||||||
w[i] = i;
|
|
||||||
}
|
|
||||||
ret->add_polygon(indices);
|
|
||||||
polygon_cache[Pair<Ref<Resource>, int>(p_polygon, p_alternative_id)] = ret;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<OccluderPolygon2D> ocd = p_polygon;
|
|
||||||
if (ocd.is_valid()) {
|
|
||||||
Ref<OccluderPolygon2D> ret;
|
|
||||||
ret.instantiate();
|
|
||||||
ret->set_polygon(_get_transformed_vertices(ocd->get_polygon(), p_alternative_id));
|
|
||||||
polygon_cache[Pair<Ref<Resource>, int>(p_polygon, p_alternative_id)] = ret;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p_polygon;
|
|
||||||
}
|
|
||||||
|
|
||||||
PackedStringArray TileMap::get_configuration_warnings() const {
|
PackedStringArray TileMap::get_configuration_warnings() const {
|
||||||
PackedStringArray warnings = Node::get_configuration_warnings();
|
PackedStringArray warnings = Node::get_configuration_warnings();
|
||||||
|
|
||||||
|
|||||||
@@ -472,10 +472,6 @@ private:
|
|||||||
|
|
||||||
void _update_notify_local_transform();
|
void _update_notify_local_transform();
|
||||||
|
|
||||||
// Polygons.
|
|
||||||
HashMap<Pair<Ref<Resource>, int>, Ref<Resource>, PairHash<Ref<Resource>, int>> polygon_cache;
|
|
||||||
PackedVector2Array _get_transformed_vertices(const PackedVector2Array &p_vertices, int p_alternative_id);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool _set(const StringName &p_name, const Variant &p_value);
|
bool _set(const StringName &p_name, const Variant &p_value);
|
||||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||||
@@ -619,7 +615,6 @@ public:
|
|||||||
// Helpers?
|
// Helpers?
|
||||||
TypedArray<Vector2i> get_surrounding_cells(const Vector2i &coords);
|
TypedArray<Vector2i> get_surrounding_cells(const Vector2i &coords);
|
||||||
void draw_cells_outline(Control *p_control, const RBSet<Vector2i> &p_cells, Color p_color, Transform2D p_transform = Transform2D());
|
void draw_cells_outline(Control *p_control, const RBSet<Vector2i> &p_cells, Color p_color, Transform2D p_transform = Transform2D());
|
||||||
Ref<Resource> get_transformed_polygon(Ref<Resource> p_polygon, int p_alternative_id);
|
|
||||||
|
|
||||||
// Virtual function to modify the TileData at runtime.
|
// Virtual function to modify the TileData at runtime.
|
||||||
GDVIRTUAL2R(bool, _use_tile_data_runtime_update, int, Vector2i);
|
GDVIRTUAL2R(bool, _use_tile_data_runtime_update, int, Vector2i);
|
||||||
|
|||||||
48
scene/resources/tile_set.compat.inc
Normal file
48
scene/resources/tile_set.compat.inc
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* tile_set.compat.inc */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
|
||||||
|
#include "tile_set.h"
|
||||||
|
|
||||||
|
Ref<NavigationPolygon> TileData::_get_navigation_polygon_bind_compat_84660(int p_layer_id) const {
|
||||||
|
return get_navigation_polygon(p_layer_id, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<OccluderPolygon2D> TileData::_get_occluder_bind_compat_84660(int p_layer_id) const {
|
||||||
|
return get_occluder(p_layer_id, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileData::_bind_compatibility_methods() {
|
||||||
|
ClassDB::bind_compatibility_method(D_METHOD("get_navigation_polygon"), &TileData::_get_navigation_polygon_bind_compat_84660);
|
||||||
|
ClassDB::bind_compatibility_method(D_METHOD("get_occluder"), &TileData::_get_occluder_bind_compat_84660);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#include "tile_set.h"
|
#include "tile_set.h"
|
||||||
|
#include "tile_set.compat.inc"
|
||||||
|
|
||||||
#include "core/io/marshalls.h"
|
#include "core/io/marshalls.h"
|
||||||
#include "core/math/geometry_2d.h"
|
#include "core/math/geometry_2d.h"
|
||||||
@@ -5104,7 +5105,7 @@ void TileData::add_occlusion_layer(int p_to_pos) {
|
|||||||
p_to_pos = occluders.size();
|
p_to_pos = occluders.size();
|
||||||
}
|
}
|
||||||
ERR_FAIL_INDEX(p_to_pos, occluders.size() + 1);
|
ERR_FAIL_INDEX(p_to_pos, occluders.size() + 1);
|
||||||
occluders.insert(p_to_pos, Ref<OccluderPolygon2D>());
|
occluders.insert(p_to_pos, OcclusionLayerTileData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileData::move_occlusion_layer(int p_from_index, int p_to_pos) {
|
void TileData::move_occlusion_layer(int p_from_index, int p_to_pos) {
|
||||||
@@ -5219,7 +5220,7 @@ void TileData::add_navigation_layer(int p_to_pos) {
|
|||||||
p_to_pos = navigation.size();
|
p_to_pos = navigation.size();
|
||||||
}
|
}
|
||||||
ERR_FAIL_INDEX(p_to_pos, navigation.size() + 1);
|
ERR_FAIL_INDEX(p_to_pos, navigation.size() + 1);
|
||||||
navigation.insert(p_to_pos, Ref<NavigationPolygon>());
|
navigation.insert(p_to_pos, NavigationLayerTileData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileData::move_navigation_layer(int p_from_index, int p_to_pos) {
|
void TileData::move_navigation_layer(int p_from_index, int p_to_pos) {
|
||||||
@@ -5365,13 +5366,35 @@ int TileData::get_y_sort_origin() const {
|
|||||||
|
|
||||||
void TileData::set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon) {
|
void TileData::set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon) {
|
||||||
ERR_FAIL_INDEX(p_layer_id, occluders.size());
|
ERR_FAIL_INDEX(p_layer_id, occluders.size());
|
||||||
occluders.write[p_layer_id] = p_occluder_polygon;
|
occluders.write[p_layer_id].occluder = p_occluder_polygon;
|
||||||
|
occluders.write[p_layer_id].transformed_occluders.clear();
|
||||||
emit_signal(SNAME("changed"));
|
emit_signal(SNAME("changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id) const {
|
Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
|
||||||
ERR_FAIL_INDEX_V(p_layer_id, occluders.size(), Ref<OccluderPolygon2D>());
|
ERR_FAIL_INDEX_V(p_layer_id, occluders.size(), Ref<OccluderPolygon2D>());
|
||||||
return occluders[p_layer_id];
|
|
||||||
|
const OcclusionLayerTileData &layer_tile_data = occluders[p_layer_id];
|
||||||
|
|
||||||
|
int key = int(p_flip_h) | int(p_flip_v) << 1 | int(p_transpose) << 2;
|
||||||
|
if (key == 0) {
|
||||||
|
return layer_tile_data.occluder;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer_tile_data.occluder.is_null()) {
|
||||||
|
return Ref<OccluderPolygon2D>();
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<int, Ref<OccluderPolygon2D>>::Iterator I = layer_tile_data.transformed_occluders.find(key);
|
||||||
|
if (!I) {
|
||||||
|
Ref<OccluderPolygon2D> transformed_polygon;
|
||||||
|
transformed_polygon.instantiate();
|
||||||
|
transformed_polygon->set_polygon(get_transformed_vertices(layer_tile_data.occluder->get_polygon(), p_flip_h, p_flip_v, p_transpose));
|
||||||
|
layer_tile_data.transformed_occluders[key] = transformed_polygon;
|
||||||
|
return transformed_polygon;
|
||||||
|
} else {
|
||||||
|
return I->value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Physics
|
// Physics
|
||||||
@@ -5431,22 +5454,25 @@ void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index,
|
|||||||
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
|
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
|
||||||
ERR_FAIL_COND_MSG(p_polygon.size() != 0 && p_polygon.size() < 3, "Invalid polygon. Needs either 0 or more than 3 points.");
|
ERR_FAIL_COND_MSG(p_polygon.size() != 0 && p_polygon.size() < 3, "Invalid polygon. Needs either 0 or more than 3 points.");
|
||||||
|
|
||||||
|
TileData::PhysicsLayerTileData::PolygonShapeTileData &polygon_shape_tile_data = physics.write[p_layer_id].polygons.write[p_polygon_index];
|
||||||
|
|
||||||
if (p_polygon.is_empty()) {
|
if (p_polygon.is_empty()) {
|
||||||
physics.write[p_layer_id].polygons.write[p_polygon_index].shapes.clear();
|
polygon_shape_tile_data.shapes.clear();
|
||||||
} else {
|
} else {
|
||||||
// Decompose into convex shapes.
|
// Decompose into convex shapes.
|
||||||
Vector<Vector<Vector2>> decomp = Geometry2D::decompose_polygon_in_convex(p_polygon);
|
Vector<Vector<Vector2>> decomp = Geometry2D::decompose_polygon_in_convex(p_polygon);
|
||||||
ERR_FAIL_COND_MSG(decomp.is_empty(), "Could not decompose the polygon into convex shapes.");
|
ERR_FAIL_COND_MSG(decomp.is_empty(), "Could not decompose the polygon into convex shapes.");
|
||||||
|
|
||||||
physics.write[p_layer_id].polygons.write[p_polygon_index].shapes.resize(decomp.size());
|
polygon_shape_tile_data.shapes.resize(decomp.size());
|
||||||
for (int i = 0; i < decomp.size(); i++) {
|
for (int i = 0; i < decomp.size(); i++) {
|
||||||
Ref<ConvexPolygonShape2D> shape;
|
Ref<ConvexPolygonShape2D> shape;
|
||||||
shape.instantiate();
|
shape.instantiate();
|
||||||
shape->set_points(decomp[i]);
|
shape->set_points(decomp[i]);
|
||||||
physics.write[p_layer_id].polygons.write[p_polygon_index].shapes[i] = shape;
|
polygon_shape_tile_data.shapes[i] = shape;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
physics.write[p_layer_id].polygons.write[p_polygon_index].polygon = p_polygon;
|
polygon_shape_tile_data.transformed_shapes.clear();
|
||||||
|
polygon_shape_tile_data.polygon = p_polygon;
|
||||||
emit_signal(SNAME("changed"));
|
emit_signal(SNAME("changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5488,11 +5514,36 @@ int TileData::get_collision_polygon_shapes_count(int p_layer_id, int p_polygon_i
|
|||||||
return physics[p_layer_id].polygons[p_polygon_index].shapes.size();
|
return physics[p_layer_id].polygons[p_polygon_index].shapes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<ConvexPolygonShape2D> TileData::get_collision_polygon_shape(int p_layer_id, int p_polygon_index, int shape_index) const {
|
Ref<ConvexPolygonShape2D> TileData::get_collision_polygon_shape(int p_layer_id, int p_polygon_index, int shape_index, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
|
||||||
ERR_FAIL_INDEX_V(p_layer_id, physics.size(), Ref<ConvexPolygonShape2D>());
|
ERR_FAIL_INDEX_V(p_layer_id, physics.size(), Ref<ConvexPolygonShape2D>());
|
||||||
ERR_FAIL_INDEX_V(p_polygon_index, physics[p_layer_id].polygons.size(), Ref<ConvexPolygonShape2D>());
|
ERR_FAIL_INDEX_V(p_polygon_index, physics[p_layer_id].polygons.size(), Ref<ConvexPolygonShape2D>());
|
||||||
ERR_FAIL_INDEX_V(shape_index, (int)physics[p_layer_id].polygons[p_polygon_index].shapes.size(), Ref<ConvexPolygonShape2D>());
|
ERR_FAIL_INDEX_V(shape_index, (int)physics[p_layer_id].polygons[p_polygon_index].shapes.size(), Ref<ConvexPolygonShape2D>());
|
||||||
return physics[p_layer_id].polygons[p_polygon_index].shapes[shape_index];
|
|
||||||
|
const PhysicsLayerTileData &layer_tile_data = physics[p_layer_id];
|
||||||
|
const PhysicsLayerTileData::PolygonShapeTileData &shapes_data = layer_tile_data.polygons[p_polygon_index];
|
||||||
|
|
||||||
|
int key = int(p_flip_h) | int(p_flip_v) << 1 | int(p_transpose) << 2;
|
||||||
|
if (key == 0) {
|
||||||
|
return shapes_data.shapes[shape_index];
|
||||||
|
}
|
||||||
|
if (shapes_data.shapes[shape_index].is_null()) {
|
||||||
|
return Ref<ConvexPolygonShape2D>();
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<int, LocalVector<Ref<ConvexPolygonShape2D>>>::Iterator I = shapes_data.transformed_shapes.find(key);
|
||||||
|
if (!I) {
|
||||||
|
int size = shapes_data.shapes.size();
|
||||||
|
shapes_data.transformed_shapes[key].resize(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Ref<ConvexPolygonShape2D> transformed_polygon;
|
||||||
|
transformed_polygon.instantiate();
|
||||||
|
transformed_polygon->set_points(get_transformed_vertices(shapes_data.shapes[shape_index]->get_points(), p_flip_h, p_flip_v, p_transpose));
|
||||||
|
shapes_data.transformed_shapes[key][i] = transformed_polygon;
|
||||||
|
}
|
||||||
|
return shapes_data.transformed_shapes[key][shape_index];
|
||||||
|
} else {
|
||||||
|
return I->value[shape_index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terrain
|
// Terrain
|
||||||
@@ -5570,13 +5621,50 @@ TileSet::TerrainsPattern TileData::get_terrains_pattern() const {
|
|||||||
// Navigation
|
// Navigation
|
||||||
void TileData::set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon) {
|
void TileData::set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon) {
|
||||||
ERR_FAIL_INDEX(p_layer_id, navigation.size());
|
ERR_FAIL_INDEX(p_layer_id, navigation.size());
|
||||||
navigation.write[p_layer_id] = p_navigation_polygon;
|
navigation.write[p_layer_id].navigation_polygon = p_navigation_polygon;
|
||||||
|
navigation.write[p_layer_id].transformed_navigation_polygon.clear();
|
||||||
emit_signal(SNAME("changed"));
|
emit_signal(SNAME("changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id) const {
|
Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_flip_h, bool p_flip_v, bool p_transpose) const {
|
||||||
ERR_FAIL_INDEX_V(p_layer_id, navigation.size(), Ref<NavigationPolygon>());
|
ERR_FAIL_INDEX_V(p_layer_id, navigation.size(), Ref<NavigationPolygon>());
|
||||||
return navigation[p_layer_id];
|
|
||||||
|
const NavigationLayerTileData &layer_tile_data = navigation[p_layer_id];
|
||||||
|
|
||||||
|
int key = int(p_flip_h) | int(p_flip_v) << 1 | int(p_transpose) << 2;
|
||||||
|
if (key == 0) {
|
||||||
|
return layer_tile_data.navigation_polygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layer_tile_data.navigation_polygon.is_null()) {
|
||||||
|
return Ref<NavigationPolygon>();
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<int, Ref<NavigationPolygon>>::Iterator I = layer_tile_data.transformed_navigation_polygon.find(key);
|
||||||
|
if (!I) {
|
||||||
|
Ref<NavigationPolygon> transformed_polygon;
|
||||||
|
transformed_polygon.instantiate();
|
||||||
|
|
||||||
|
PackedVector2Array new_points = get_transformed_vertices(layer_tile_data.navigation_polygon->get_vertices(), p_flip_h, p_flip_v, p_transpose);
|
||||||
|
transformed_polygon->set_vertices(new_points);
|
||||||
|
|
||||||
|
for (int i = 0; i < layer_tile_data.navigation_polygon->get_outline_count(); i++) {
|
||||||
|
PackedVector2Array new_outline = get_transformed_vertices(layer_tile_data.navigation_polygon->get_outline(i), p_flip_h, p_flip_v, p_transpose);
|
||||||
|
transformed_polygon->add_outline(new_outline);
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedInt32Array indices;
|
||||||
|
indices.resize(new_points.size());
|
||||||
|
int *w = indices.ptrw();
|
||||||
|
for (int i = 0; i < new_points.size(); i++) {
|
||||||
|
w[i] = i;
|
||||||
|
}
|
||||||
|
transformed_polygon->add_polygon(indices);
|
||||||
|
layer_tile_data.transformed_navigation_polygon[key] = transformed_polygon;
|
||||||
|
return transformed_polygon;
|
||||||
|
} else {
|
||||||
|
return I->value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
@@ -5615,6 +5703,33 @@ Variant TileData::get_custom_data_by_layer_id(int p_layer_id) const {
|
|||||||
return custom_data[p_layer_id];
|
return custom_data[p_layer_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PackedVector2Array TileData::get_transformed_vertices(const PackedVector2Array &p_vertices, bool p_flip_h, bool p_flip_v, bool p_transpose) {
|
||||||
|
const Vector2 *r = p_vertices.ptr();
|
||||||
|
int size = p_vertices.size();
|
||||||
|
|
||||||
|
PackedVector2Array new_points;
|
||||||
|
new_points.resize(size);
|
||||||
|
Vector2 *w = new_points.ptrw();
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Vector2 v;
|
||||||
|
if (p_transpose) {
|
||||||
|
v = Vector2(r[i].y, r[i].x);
|
||||||
|
} else {
|
||||||
|
v = r[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_flip_h) {
|
||||||
|
v.x *= -1;
|
||||||
|
}
|
||||||
|
if (p_flip_v) {
|
||||||
|
v.y *= -1;
|
||||||
|
}
|
||||||
|
w[i] = v;
|
||||||
|
}
|
||||||
|
return new_points;
|
||||||
|
}
|
||||||
|
|
||||||
bool TileData::_set(const StringName &p_name, const Variant &p_value) {
|
bool TileData::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
if (p_name == "texture_offset") {
|
if (p_name == "texture_offset") {
|
||||||
@@ -5845,7 +5960,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||||||
for (int i = 0; i < occluders.size(); i++) {
|
for (int i = 0; i < occluders.size(); i++) {
|
||||||
// occlusion_layer_%d/polygon
|
// occlusion_layer_%d/polygon
|
||||||
property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT);
|
property_info = PropertyInfo(Variant::OBJECT, vformat("occlusion_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D", PROPERTY_USAGE_DEFAULT);
|
||||||
if (!occluders[i].is_valid()) {
|
if (occluders[i].occluder.is_null()) {
|
||||||
property_info.usage ^= PROPERTY_USAGE_STORAGE;
|
property_info.usage ^= PROPERTY_USAGE_STORAGE;
|
||||||
}
|
}
|
||||||
p_list->push_back(property_info);
|
p_list->push_back(property_info);
|
||||||
@@ -5901,7 +6016,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||||||
p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Navigation", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
|
p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Navigation", ""), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
|
||||||
for (int i = 0; i < navigation.size(); i++) {
|
for (int i = 0; i < navigation.size(); i++) {
|
||||||
property_info = PropertyInfo(Variant::OBJECT, vformat("navigation_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_DEFAULT);
|
property_info = PropertyInfo(Variant::OBJECT, vformat("navigation_layer_%d/%s", i, PNAME("polygon")), PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon", PROPERTY_USAGE_DEFAULT);
|
||||||
if (!navigation[i].is_valid()) {
|
if (navigation[i].navigation_polygon.is_null()) {
|
||||||
property_info.usage ^= PROPERTY_USAGE_STORAGE;
|
property_info.usage ^= PROPERTY_USAGE_STORAGE;
|
||||||
}
|
}
|
||||||
p_list->push_back(property_info);
|
p_list->push_back(property_info);
|
||||||
@@ -5942,7 +6057,7 @@ void TileData::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_y_sort_origin"), &TileData::get_y_sort_origin);
|
ClassDB::bind_method(D_METHOD("get_y_sort_origin"), &TileData::get_y_sort_origin);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_occluder", "layer_id", "occluder_polygon"), &TileData::set_occluder);
|
ClassDB::bind_method(D_METHOD("set_occluder", "layer_id", "occluder_polygon"), &TileData::set_occluder);
|
||||||
ClassDB::bind_method(D_METHOD("get_occluder", "layer_id"), &TileData::get_occluder);
|
ClassDB::bind_method(D_METHOD("get_occluder", "layer_id", "flip_h", "flip_v", "transpose"), &TileData::get_occluder, DEFVAL(false), DEFVAL(false), DEFVAL(false));
|
||||||
|
|
||||||
// Physics.
|
// Physics.
|
||||||
ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "layer_id", "velocity"), &TileData::set_constant_linear_velocity);
|
ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "layer_id", "velocity"), &TileData::set_constant_linear_velocity);
|
||||||
@@ -5970,7 +6085,7 @@ void TileData::_bind_methods() {
|
|||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
ClassDB::bind_method(D_METHOD("set_navigation_polygon", "layer_id", "navigation_polygon"), &TileData::set_navigation_polygon);
|
ClassDB::bind_method(D_METHOD("set_navigation_polygon", "layer_id", "navigation_polygon"), &TileData::set_navigation_polygon);
|
||||||
ClassDB::bind_method(D_METHOD("get_navigation_polygon", "layer_id"), &TileData::get_navigation_polygon);
|
ClassDB::bind_method(D_METHOD("get_navigation_polygon", "layer_id", "flip_h", "flip_v", "transpose"), &TileData::get_navigation_polygon, DEFVAL(false), DEFVAL(false), DEFVAL(false));
|
||||||
|
|
||||||
// Misc.
|
// Misc.
|
||||||
ClassDB::bind_method(D_METHOD("set_probability", "probability"), &TileData::set_probability);
|
ClassDB::bind_method(D_METHOD("set_probability", "probability"), &TileData::set_probability);
|
||||||
|
|||||||
@@ -815,13 +815,18 @@ private:
|
|||||||
Color modulate = Color(1.0, 1.0, 1.0, 1.0);
|
Color modulate = Color(1.0, 1.0, 1.0, 1.0);
|
||||||
int z_index = 0;
|
int z_index = 0;
|
||||||
int y_sort_origin = 0;
|
int y_sort_origin = 0;
|
||||||
Vector<Ref<OccluderPolygon2D>> occluders;
|
struct OcclusionLayerTileData {
|
||||||
|
Ref<OccluderPolygon2D> occluder;
|
||||||
|
mutable HashMap<int, Ref<OccluderPolygon2D>> transformed_occluders;
|
||||||
|
};
|
||||||
|
Vector<OcclusionLayerTileData> occluders;
|
||||||
|
|
||||||
// Physics
|
// Physics
|
||||||
struct PhysicsLayerTileData {
|
struct PhysicsLayerTileData {
|
||||||
struct PolygonShapeTileData {
|
struct PolygonShapeTileData {
|
||||||
LocalVector<Vector2> polygon;
|
LocalVector<Vector2> polygon;
|
||||||
LocalVector<Ref<ConvexPolygonShape2D>> shapes;
|
LocalVector<Ref<ConvexPolygonShape2D>> shapes;
|
||||||
|
mutable HashMap<int, LocalVector<Ref<ConvexPolygonShape2D>>> transformed_shapes;
|
||||||
bool one_way = false;
|
bool one_way = false;
|
||||||
float one_way_margin = 1.0;
|
float one_way_margin = 1.0;
|
||||||
};
|
};
|
||||||
@@ -839,7 +844,11 @@ private:
|
|||||||
int terrain_peering_bits[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
|
int terrain_peering_bits[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
Vector<Ref<NavigationPolygon>> navigation;
|
struct NavigationLayerTileData {
|
||||||
|
Ref<NavigationPolygon> navigation_polygon;
|
||||||
|
mutable HashMap<int, Ref<NavigationPolygon>> transformed_navigation_polygon;
|
||||||
|
};
|
||||||
|
Vector<NavigationLayerTileData> navigation;
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
double probability = 1.0;
|
double probability = 1.0;
|
||||||
@@ -853,6 +862,13 @@ protected:
|
|||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
Ref<NavigationPolygon> _get_navigation_polygon_bind_compat_84660(int p_layer_id) const;
|
||||||
|
Ref<OccluderPolygon2D> _get_occluder_bind_compat_84660(int p_layer_id) const;
|
||||||
|
|
||||||
|
static void _bind_compatibility_methods();
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Not exposed.
|
// Not exposed.
|
||||||
void set_tile_set(const TileSet *p_tile_set);
|
void set_tile_set(const TileSet *p_tile_set);
|
||||||
@@ -901,7 +917,7 @@ public:
|
|||||||
int get_y_sort_origin() const;
|
int get_y_sort_origin() const;
|
||||||
|
|
||||||
void set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon);
|
void set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon);
|
||||||
Ref<OccluderPolygon2D> get_occluder(int p_layer_id) const;
|
Ref<OccluderPolygon2D> get_occluder(int p_layer_id, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false) const;
|
||||||
|
|
||||||
// Physics
|
// Physics
|
||||||
void set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity);
|
void set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity);
|
||||||
@@ -919,7 +935,7 @@ public:
|
|||||||
void set_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index, float p_one_way_margin);
|
void set_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index, float p_one_way_margin);
|
||||||
float get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const;
|
float get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const;
|
||||||
int get_collision_polygon_shapes_count(int p_layer_id, int p_polygon_index) const;
|
int get_collision_polygon_shapes_count(int p_layer_id, int p_polygon_index) const;
|
||||||
Ref<ConvexPolygonShape2D> get_collision_polygon_shape(int p_layer_id, int p_polygon_index, int shape_index) const;
|
Ref<ConvexPolygonShape2D> get_collision_polygon_shape(int p_layer_id, int p_polygon_index, int shape_index, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false) const;
|
||||||
|
|
||||||
// Terrain
|
// Terrain
|
||||||
void set_terrain_set(int p_terrain_id);
|
void set_terrain_set(int p_terrain_id);
|
||||||
@@ -934,7 +950,7 @@ public:
|
|||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
void set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon);
|
void set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon);
|
||||||
Ref<NavigationPolygon> get_navigation_polygon(int p_layer_id) const;
|
Ref<NavigationPolygon> get_navigation_polygon(int p_layer_id, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false) const;
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
void set_probability(float p_probability);
|
void set_probability(float p_probability);
|
||||||
@@ -945,6 +961,9 @@ public:
|
|||||||
Variant get_custom_data(String p_layer_name) const;
|
Variant get_custom_data(String p_layer_name) const;
|
||||||
void set_custom_data_by_layer_id(int p_layer_id, Variant p_value);
|
void set_custom_data_by_layer_id(int p_layer_id, Variant p_value);
|
||||||
Variant get_custom_data_by_layer_id(int p_layer_id) const;
|
Variant get_custom_data_by_layer_id(int p_layer_id) const;
|
||||||
|
|
||||||
|
// Polygons.
|
||||||
|
static PackedVector2Array get_transformed_vertices(const PackedVector2Array &p_vertices, bool p_flip_h, bool p_flip_v, bool p_transpose);
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(TileSet::CellNeighbor);
|
VARIANT_ENUM_CAST(TileSet::CellNeighbor);
|
||||||
|
|||||||
Reference in New Issue
Block a user