mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
Expose TriangleMesh api functions wrapped for scripting
Adds script wrapped TriangleMesh api functions to create and query the triangle BVH tree.
This commit is contained in:
parent
c7ea8614d7
commit
f2197a1013
5 changed files with 250 additions and 12 deletions
|
|
@ -182,7 +182,11 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t>
|
|||
valid = true;
|
||||
}
|
||||
|
||||
bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const {
|
||||
bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
|
||||
|
||||
enum {
|
||||
|
|
@ -234,6 +238,9 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
|
|||
if (r_surf_index) {
|
||||
*r_surf_index = s.surface_index;
|
||||
}
|
||||
if (r_face_index) {
|
||||
*r_face_index = b.face_index;
|
||||
}
|
||||
inters = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -283,7 +290,11 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
|
|||
return inters;
|
||||
}
|
||||
|
||||
bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const {
|
||||
bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index, int32_t *r_face_index) const {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
|
||||
|
||||
enum {
|
||||
|
|
@ -335,6 +346,9 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
|
|||
if (r_surf_index) {
|
||||
*r_surf_index = s.surface_index;
|
||||
}
|
||||
if (r_face_index) {
|
||||
*r_face_index = b.face_index;
|
||||
}
|
||||
inters = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -385,6 +399,10 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
|
|||
}
|
||||
|
||||
bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale) const {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
|
||||
|
||||
enum {
|
||||
|
|
@ -503,6 +521,85 @@ Vector<Face3> TriangleMesh::get_faces() const {
|
|||
return faces;
|
||||
}
|
||||
|
||||
bool TriangleMesh::create_from_faces(const Vector<Vector3> &p_faces) {
|
||||
create(p_faces);
|
||||
return is_valid();
|
||||
}
|
||||
|
||||
Dictionary TriangleMesh::intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const {
|
||||
if (!valid) {
|
||||
return Dictionary();
|
||||
}
|
||||
|
||||
Vector3 r_point;
|
||||
Vector3 r_normal;
|
||||
int32_t r_face_index = -1;
|
||||
|
||||
bool intersected = intersect_segment(p_begin, p_end, r_point, r_normal, nullptr, &r_face_index);
|
||||
if (!intersected) {
|
||||
return Dictionary();
|
||||
}
|
||||
|
||||
Dictionary result;
|
||||
result["position"] = r_point;
|
||||
result["normal"] = r_normal;
|
||||
result["face_index"] = r_face_index;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Dictionary TriangleMesh::intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const {
|
||||
if (!valid) {
|
||||
return Dictionary();
|
||||
}
|
||||
|
||||
Vector3 r_point;
|
||||
Vector3 r_normal;
|
||||
int32_t r_face_index = -1;
|
||||
|
||||
bool intersected = intersect_ray(p_begin, p_dir, r_point, r_normal, nullptr, &r_face_index);
|
||||
if (!intersected) {
|
||||
return Dictionary();
|
||||
}
|
||||
|
||||
Dictionary result;
|
||||
result["position"] = r_point;
|
||||
result["normal"] = r_normal;
|
||||
result["face_index"] = r_face_index;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector<Vector3> TriangleMesh::get_faces_scriptwrap() const {
|
||||
if (!valid) {
|
||||
return Vector<Vector3>();
|
||||
}
|
||||
|
||||
Vector<Vector3> faces;
|
||||
int ts = triangles.size();
|
||||
faces.resize(triangles.size() * 3);
|
||||
|
||||
Vector3 *w = faces.ptrw();
|
||||
const Triangle *r = triangles.ptr();
|
||||
const Vector3 *rv = vertices.ptr();
|
||||
|
||||
for (int i = 0; i < ts; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
w[i * 3 + j] = rv[r[i].indices[j]];
|
||||
}
|
||||
}
|
||||
|
||||
return faces;
|
||||
}
|
||||
|
||||
void TriangleMesh::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("create_from_faces", "faces"), &TriangleMesh::create_from_faces);
|
||||
ClassDB::bind_method(D_METHOD("get_faces"), &TriangleMesh::get_faces_scriptwrap);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("intersect_segment", "begin", "end"), &TriangleMesh::intersect_segment_scriptwrap);
|
||||
ClassDB::bind_method(D_METHOD("intersect_ray", "begin", "dir"), &TriangleMesh::intersect_ray_scriptwrap);
|
||||
}
|
||||
|
||||
TriangleMesh::TriangleMesh() {
|
||||
valid = false;
|
||||
max_depth = 0;
|
||||
|
|
|
|||
|
|
@ -40,9 +40,12 @@ public:
|
|||
struct Triangle {
|
||||
Vector3 normal;
|
||||
int indices[3];
|
||||
int32_t surface_index;
|
||||
int32_t surface_index = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
Vector<Triangle> triangles;
|
||||
Vector<Vector3> vertices;
|
||||
|
|
@ -50,10 +53,10 @@ private:
|
|||
struct BVH {
|
||||
AABB aabb;
|
||||
Vector3 center; //used for sorting
|
||||
int left;
|
||||
int right;
|
||||
int left = -1;
|
||||
int right = -1;
|
||||
|
||||
int face_index;
|
||||
int32_t face_index = -1;
|
||||
};
|
||||
|
||||
struct BVHCmpX {
|
||||
|
|
@ -76,13 +79,13 @@ private:
|
|||
int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc);
|
||||
|
||||
Vector<BVH> bvh;
|
||||
int max_depth;
|
||||
bool valid;
|
||||
int max_depth = 0;
|
||||
bool valid = false;
|
||||
|
||||
public:
|
||||
bool is_valid() const;
|
||||
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const;
|
||||
bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const;
|
||||
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const;
|
||||
bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr, int32_t *r_face_index = nullptr) const;
|
||||
bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const;
|
||||
Vector<Face3> get_faces() const;
|
||||
|
||||
|
|
@ -91,5 +94,13 @@ public:
|
|||
void get_indices(Vector<int> *r_triangles_indices) const;
|
||||
|
||||
void create(const Vector<Vector3> &p_faces, const Vector<int32_t> &p_surface_indices = Vector<int32_t>());
|
||||
|
||||
// Wrapped functions for compatibility with method bindings
|
||||
// and user exposed script api that can't use more native types.
|
||||
bool create_from_faces(const Vector<Vector3> &p_faces);
|
||||
Dictionary intersect_segment_scriptwrap(const Vector3 &p_begin, const Vector3 &p_end) const;
|
||||
Dictionary intersect_ray_scriptwrap(const Vector3 &p_begin, const Vector3 &p_dir) const;
|
||||
Vector<Vector3> get_faces_scriptwrap() const;
|
||||
|
||||
TriangleMesh();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue