1/**************************************************************************/
2/* concave_polygon_shape_3d.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "concave_polygon_shape_3d.h"
32
33#include "servers/physics_server_3d.h"
34
35Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() const {
36 HashSet<DrawEdge, DrawEdge> edges;
37
38 int index_count = faces.size();
39 ERR_FAIL_COND_V((index_count % 3) != 0, Vector<Vector3>());
40
41 const Vector3 *r = faces.ptr();
42
43 for (int i = 0; i < index_count; i += 3) {
44 for (int j = 0; j < 3; j++) {
45 DrawEdge de(r[i + j], r[i + ((j + 1) % 3)]);
46 edges.insert(de);
47 }
48 }
49
50 Vector<Vector3> points;
51 points.resize(edges.size() * 2);
52 int idx = 0;
53 for (const DrawEdge &E : edges) {
54 points.write[idx + 0] = E.a;
55 points.write[idx + 1] = E.b;
56 idx += 2;
57 }
58
59 return points;
60}
61
62real_t ConcavePolygonShape3D::get_enclosing_radius() const {
63 Vector<Vector3> data = get_faces();
64 const Vector3 *read = data.ptr();
65 real_t r = 0.0;
66 for (int i(0); i < data.size(); i++) {
67 r = MAX(read[i].length_squared(), r);
68 }
69 return Math::sqrt(r);
70}
71
72void ConcavePolygonShape3D::_update_shape() {
73 Dictionary d;
74 d["faces"] = faces;
75 d["backface_collision"] = backface_collision;
76 PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), d);
77
78 Shape3D::_update_shape();
79}
80
81void ConcavePolygonShape3D::set_faces(const Vector<Vector3> &p_faces) {
82 faces = p_faces;
83 _update_shape();
84 emit_changed();
85}
86
87Vector<Vector3> ConcavePolygonShape3D::get_faces() const {
88 return faces;
89}
90
91void ConcavePolygonShape3D::set_backface_collision_enabled(bool p_enabled) {
92 backface_collision = p_enabled;
93
94 if (!faces.is_empty()) {
95 _update_shape();
96 emit_changed();
97 }
98}
99
100bool ConcavePolygonShape3D::is_backface_collision_enabled() const {
101 return backface_collision;
102}
103
104void ConcavePolygonShape3D::_bind_methods() {
105 ClassDB::bind_method(D_METHOD("set_faces", "faces"), &ConcavePolygonShape3D::set_faces);
106 ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape3D::get_faces);
107
108 ClassDB::bind_method(D_METHOD("set_backface_collision_enabled", "enabled"), &ConcavePolygonShape3D::set_backface_collision_enabled);
109 ClassDB::bind_method(D_METHOD("is_backface_collision_enabled"), &ConcavePolygonShape3D::is_backface_collision_enabled);
110
111 ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces");
112 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "backface_collision"), "set_backface_collision_enabled", "is_backface_collision_enabled");
113}
114
115ConcavePolygonShape3D::ConcavePolygonShape3D() :
116 Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONCAVE_POLYGON)) {
117 //set_planes(Vector3(1,1,1));
118}
119