Modify Earcut and Triangulization Library to Work With Godot::Vector2
Allows use to ease some pain when converting PackedVector2Array to std::vector<Vector2>.
This commit is contained in:
BIN
.sconsign.dblite
BIN
.sconsign.dblite
Binary file not shown.
Binary file not shown.
@@ -14,12 +14,6 @@ shadow_enabled = true
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_ig7tw")
|
||||
|
||||
[node name="Polygon2D" type="Polygon2D" parent="."]
|
||||
|
||||
[node name="Polygon2D2" type="Polygon2D" parent="."]
|
||||
|
||||
[node name="Polygon2D3" type="Polygon2D" parent="."]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.99687606, -0.078981146, 0, 0.078981146, 0.99687606, 1.3097496, 0.96856904, 8.280736)
|
||||
current = true
|
||||
|
||||
@@ -14,20 +14,6 @@ var _v_points = []
|
||||
|
||||
var edges = {}
|
||||
|
||||
# returns debug lines to be drawn by callers DrawDebug3D
|
||||
#var _debug_lines: Array[PackedVector3Array]:
|
||||
#get:
|
||||
#if !_debug_lines:
|
||||
#for results in self._triangles:
|
||||
#var triangle_lines: PackedVector3Array = []
|
||||
#for vector_index in range(len(results)):
|
||||
#var v1: Vector2 = results[vector_index]
|
||||
#var v2: Vector2 = results[(vector_index+1) % CHUNK_RESULT]
|
||||
#triangle_lines.append(Vector3(v1.x, v1.y, 0))
|
||||
#triangle_lines.append(Vector3(v2.x, v2.y, 0))
|
||||
#_debug_lines.push_back(triangle_lines)
|
||||
#return _debug_lines
|
||||
|
||||
func _init(vector_indexes: PackedInt32Array, vector_points: PackedVector2Array, depth: float = -2.0):
|
||||
assert(len(vector_indexes) % 3 == 0, "Number of vertex points is not divisible by 3, invalid triangle verticies")
|
||||
surface_array.resize(Mesh.ARRAY_MAX)
|
||||
|
||||
@@ -8,35 +8,31 @@ class_name GeoPolyTriangulization
|
||||
const CHUNK_RESULT: int = 3
|
||||
|
||||
# the boundary polygon
|
||||
var _outer_polygon: Polygon2D
|
||||
var _outer_polygon: PackedVector2Array
|
||||
|
||||
# inner polygons (holes)
|
||||
var _inner_polygons: Array[Polygon2D]
|
||||
var _inner_polygons: Array[PackedVector2Array]
|
||||
|
||||
# all vector points defined by outer and inner polygons
|
||||
var vectors: PackedVector2Array = []
|
||||
|
||||
var _edge_safety: float = 0.0
|
||||
|
||||
func _init(outer_polygon: Polygon2D, inner_polygons: Array[Polygon2D], edge_safety: float):
|
||||
func _init(outer_polygon: PackedVector2Array, inner_polygons: Array[PackedVector2Array], edge_safety: float):
|
||||
self._outer_polygon = outer_polygon
|
||||
self._inner_polygons = inner_polygons
|
||||
self._edge_safety = edge_safety
|
||||
|
||||
# create a polygon that will be used to intesect the hole and control where they can destoy the wall
|
||||
var intersect_polygon = Polygon2D.new()
|
||||
# calulate the new smaller polygon
|
||||
intersect_polygon.polygon = Geometry2D.offset_polygon(outer_polygon.polygon, self._edge_safety)[0]
|
||||
print(intersect_polygon.polygon)
|
||||
# calulate boundary
|
||||
var hole_boundary = Geometry2D.offset_polygon(outer_polygon, self._edge_safety)[0]
|
||||
|
||||
for ip in inner_polygons:
|
||||
var new_hole = Geometry2D.intersect_polygons(intersect_polygon.polygon, ip.polygon)[0]
|
||||
ip.polygon = new_hole
|
||||
var new_hole = Geometry2D.intersect_polygons(hole_boundary, ip)[0]
|
||||
self._inner_polygons.append(new_hole)
|
||||
|
||||
self.vectors.append_array(self._outer_polygon.polygon)
|
||||
self.vectors.append_array(self._outer_polygon)
|
||||
|
||||
for inner_polygon in self._inner_polygons:
|
||||
self.vectors.append_array(inner_polygon.polygon)
|
||||
self.vectors.append_array(inner_polygon)
|
||||
|
||||
# returns all triangles generated by ear clipping the outer and inner polygons
|
||||
func triangulate() -> PackedInt32Array:
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
extends Node
|
||||
|
||||
@onready var p1 = $Polygon2D
|
||||
@onready var p2 = $Polygon2D2
|
||||
@onready var p3 = $Polygon2D3
|
||||
|
||||
@onready var meshInstance = MeshInstance3D.new()
|
||||
|
||||
var lines = []
|
||||
@@ -16,22 +12,13 @@ func _process(delta: float) -> void:
|
||||
meshInstance.rotate(Vector3.RIGHT, (0.9 * delta))
|
||||
|
||||
func _ready() -> void:
|
||||
var p1_vectors = [Vector2(4, 0), Vector2(4, 4), Vector2(0, 4), Vector2(0, 0)]
|
||||
var p2_vectors = [Vector2(0, 2), Vector2(0, 1), Vector2(2, 1), Vector2(2, 2)]
|
||||
var p3_vectors = [Vector2(2, 2), Vector2(2, 1), Vector2(4, 1), Vector2(4, 2)]
|
||||
var p1 = [Vector2(4, 0), Vector2(4, 4), Vector2(0, 4), Vector2(0, 0)]
|
||||
var p2 = [Vector2(0, 2), Vector2(0, 1), Vector2(2, 1), Vector2(2, 2)]
|
||||
var p3 = [Vector2(2, 2), Vector2(2, 1), Vector2(4, 1), Vector2(4, 2)]
|
||||
|
||||
p2_vectors.reverse()
|
||||
p3_vectors.reverse()
|
||||
|
||||
p1.polygon = p1_vectors
|
||||
p2.polygon = p2_vectors
|
||||
p3.polygon = p3_vectors
|
||||
|
||||
p2.color = Color(1, 0, 1)
|
||||
|
||||
var trianglizationInstance = GeoPolyTriangulization.new(p1, [p2, p3], -0.001)
|
||||
var trianglizationInstance = GeoPolyTriangulization.new(PackedVector2Array(p1), [PackedVector2Array(p2), PackedVector2Array(p3)], -0.001)
|
||||
var vector_indexes = trianglizationInstance.triangulate()
|
||||
print(vector_indexes)
|
||||
var vectors_points = trianglizationInstance.vectors
|
||||
|
||||
var meshGenerator = GeoPolyMesh.new(vector_indexes, vectors_points)
|
||||
|
||||
@@ -20,6 +20,12 @@ template <std::size_t I, typename T> struct nth {
|
||||
return std::get<I>(t);
|
||||
};
|
||||
};
|
||||
template <> struct nth<0, godot::Vector2> {
|
||||
inline static auto get(const godot::Vector2 &t) { return t.x; };
|
||||
};
|
||||
template <> struct nth<1, godot::Vector2> {
|
||||
inline static auto get(const godot::Vector2 &t) { return t.y; };
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
|
||||
|
||||
BIN
src/gdexample.os
BIN
src/gdexample.os
Binary file not shown.
@@ -1,15 +1,12 @@
|
||||
#include "triangulization.hpp"
|
||||
#include "earcut.hpp"
|
||||
#include "godot_cpp/classes/polygon2d.hpp"
|
||||
#include "godot_cpp/core/class_db.hpp"
|
||||
#include "godot_cpp/variant/array.hpp"
|
||||
#include "godot_cpp/variant/packed_int32_array.hpp"
|
||||
#include "godot_cpp/variant/packed_vector2_array.hpp"
|
||||
#include "godot_cpp/variant/string.hpp"
|
||||
#include "godot_cpp/variant/typed_array.hpp"
|
||||
#include "godot_cpp/variant/utility_functions.hpp"
|
||||
#include "godot_cpp/variant/vector2.hpp"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
@@ -21,39 +18,29 @@ void Triangulization::_bind_methods() {
|
||||
&Triangulization::triangulate_with_holes);
|
||||
}
|
||||
|
||||
std::vector<std::array<double, 2>>
|
||||
_convert_to_std_vec(const godot::PackedVector2Array &packed_array) {
|
||||
std::vector<std::array<double, 2>> std_vec;
|
||||
std::vector<Vector2>
|
||||
_convert_to_std_vec2(const godot::PackedVector2Array &packed_array) {
|
||||
std::vector<Vector2> std_vec;
|
||||
std_vec.reserve(packed_array.size());
|
||||
|
||||
for (int i = 0; i < packed_array.size(); i++) {
|
||||
Vector2 tmp = packed_array[i];
|
||||
std_vec.push_back({tmp.x, tmp.y});
|
||||
std_vec.push_back(packed_array.get(i));
|
||||
}
|
||||
|
||||
return std_vec;
|
||||
}
|
||||
|
||||
PackedInt32Array
|
||||
Triangulization::triangulate_with_holes(const Polygon2D *outer,
|
||||
const TypedArray<Polygon2D> &inner) {
|
||||
std::vector<std::vector<std::array<double, 2>>> p;
|
||||
PackedInt32Array Triangulization::triangulate_with_holes(
|
||||
const PackedVector2Array &outer,
|
||||
const TypedArray<PackedVector2Array> &inner) {
|
||||
std::vector<std::vector<Vector2>> p;
|
||||
|
||||
p.push_back(_convert_to_std_vec(outer->get_polygon()));
|
||||
p.push_back(_convert_to_std_vec2(outer));
|
||||
|
||||
for (int i = 0; i < inner.size(); i++) {
|
||||
Polygon2D *polygon = Object::cast_to<Polygon2D>(inner[i]);
|
||||
p.push_back(_convert_to_std_vec(polygon->get_polygon()));
|
||||
p.push_back(_convert_to_std_vec2(inner[i]));
|
||||
}
|
||||
|
||||
// for (int i = 0; i < p.size(); i++) {
|
||||
// for (int j = 0; j < p[i].size(); j++) {
|
||||
// UtilityFunctions::print(String("Value: "),
|
||||
// String::num_uint64(p[i][j][0]),
|
||||
// String(","), String::num_uint64(p[i][j][1]));
|
||||
// }
|
||||
// }
|
||||
|
||||
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(p);
|
||||
|
||||
PackedInt32Array return_values;
|
||||
|
||||
@@ -16,6 +16,7 @@ protected:
|
||||
public:
|
||||
Triangulization();
|
||||
|
||||
PackedInt32Array triangulate_with_holes(const Polygon2D *inner,
|
||||
const TypedArray<Polygon2D> &outer);
|
||||
PackedInt32Array
|
||||
triangulate_with_holes(const PackedVector2Array &outer,
|
||||
const TypedArray<PackedVector2Array> &inner);
|
||||
};
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user