1/**************************************************************************/
2/* 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 "shape_3d.h"
32
33#include "core/os/os.h"
34#include "scene/main/scene_tree.h"
35#include "scene/resources/mesh.h"
36#include "servers/physics_server_3d.h"
37
38void Shape3D::add_vertices_to_array(Vector<Vector3> &array, const Transform3D &p_xform) {
39 Vector<Vector3> toadd = get_debug_mesh_lines();
40
41 if (toadd.size()) {
42 int base = array.size();
43 array.resize(base + toadd.size());
44 Vector3 *w = array.ptrw();
45 for (int i = 0; i < toadd.size(); i++) {
46 w[i + base] = p_xform.xform(toadd[i]);
47 }
48 }
49}
50
51void Shape3D::set_custom_solver_bias(real_t p_bias) {
52 custom_bias = p_bias;
53 PhysicsServer3D::get_singleton()->shape_set_custom_solver_bias(shape, custom_bias);
54}
55
56real_t Shape3D::get_custom_solver_bias() const {
57 return custom_bias;
58}
59
60real_t Shape3D::get_margin() const {
61 return margin;
62}
63
64void Shape3D::set_margin(real_t p_margin) {
65 margin = p_margin;
66 PhysicsServer3D::get_singleton()->shape_set_margin(shape, margin);
67}
68
69Ref<ArrayMesh> Shape3D::get_debug_mesh() {
70 if (debug_mesh_cache.is_valid()) {
71 return debug_mesh_cache;
72 }
73
74 Vector<Vector3> lines = get_debug_mesh_lines();
75
76 debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh));
77
78 if (!lines.is_empty()) {
79 //make mesh
80 Vector<Vector3> array;
81 array.resize(lines.size());
82 {
83 Vector3 *w = array.ptrw();
84 for (int i = 0; i < lines.size(); i++) {
85 w[i] = lines[i];
86 }
87 }
88
89 Array arr;
90 arr.resize(Mesh::ARRAY_MAX);
91 arr[Mesh::ARRAY_VERTEX] = array;
92
93 SceneTree *st = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop());
94
95 debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, arr);
96
97 if (st) {
98 debug_mesh_cache->surface_set_material(0, st->get_debug_collision_material());
99 }
100 }
101
102 return debug_mesh_cache;
103}
104
105void Shape3D::_update_shape() {
106 emit_changed();
107 debug_mesh_cache.unref();
108}
109
110void Shape3D::_bind_methods() {
111 ClassDB::bind_method(D_METHOD("set_custom_solver_bias", "bias"), &Shape3D::set_custom_solver_bias);
112 ClassDB::bind_method(D_METHOD("get_custom_solver_bias"), &Shape3D::get_custom_solver_bias);
113
114 ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape3D::set_margin);
115 ClassDB::bind_method(D_METHOD("get_margin"), &Shape3D::get_margin);
116
117 ClassDB::bind_method(D_METHOD("get_debug_mesh"), &Shape3D::get_debug_mesh);
118
119 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias");
120 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,10,0.001,or_greater,suffix:m"), "set_margin", "get_margin");
121}
122
123Shape3D::Shape3D() {
124 ERR_PRINT("Default constructor must not be called!");
125}
126
127Shape3D::Shape3D(RID p_shape) :
128 shape(p_shape) {}
129
130Shape3D::~Shape3D() {
131 ERR_FAIL_NULL(PhysicsServer3D::get_singleton());
132 PhysicsServer3D::get_singleton()->free(shape);
133}
134