|
@@ -30,6 +30,7 @@
|
|
|
|
|
|
#include "collision_object.h"
|
|
#include "collision_object.h"
|
|
|
|
|
|
|
|
+#include "mesh_instance.h"
|
|
#include "scene/scene_string_names.h"
|
|
#include "scene/scene_string_names.h"
|
|
#include "servers/physics_server.h"
|
|
#include "servers/physics_server.h"
|
|
|
|
|
|
@@ -113,6 +114,43 @@ void CollisionObject::_update_pickable() {
|
|
PhysicsServer::get_singleton()->body_set_ray_pickable(rid, pickable);
|
|
PhysicsServer::get_singleton()->body_set_ray_pickable(rid, pickable);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void CollisionObject::_update_debug_shapes() {
|
|
|
|
+ for (Set<uint32_t>::Element *shapedata_idx = debug_shapes_to_update.front(); shapedata_idx; shapedata_idx = shapedata_idx->next()) {
|
|
|
|
+ if (shapes.has(shapedata_idx->get())) {
|
|
|
|
+ ShapeData &shapedata = shapes[shapedata_idx->get()];
|
|
|
|
+ for (int i = 0; i < shapedata.shapes.size(); i++) {
|
|
|
|
+ ShapeData::ShapeBase &s = shapedata.shapes.write[i];
|
|
|
|
+ if (s.debug_shape) {
|
|
|
|
+ s.debug_shape->queue_delete();
|
|
|
|
+ s.debug_shape = nullptr;
|
|
|
|
+ }
|
|
|
|
+ if (s.shape.is_null() || shapedata.disabled) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Ref<Mesh> mesh = s.shape->get_debug_mesh();
|
|
|
|
+ MeshInstance *mi = memnew(MeshInstance);
|
|
|
|
+ mi->set_transform(shapedata.xform);
|
|
|
|
+ mi->set_mesh(mesh);
|
|
|
|
+ add_child(mi);
|
|
|
|
+
|
|
|
|
+ mi->force_update_transform();
|
|
|
|
+ s.debug_shape = mi;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ debug_shapes_to_update.clear();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CollisionObject::_update_shape_data(uint32_t p_owner) {
|
|
|
|
+ if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
|
|
|
|
+ if (debug_shapes_to_update.empty()) {
|
|
|
|
+ call_deferred("_update_debug_shapes");
|
|
|
|
+ }
|
|
|
|
+ debug_shapes_to_update.insert(p_owner);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void CollisionObject::set_ray_pickable(bool p_ray_pickable) {
|
|
void CollisionObject::set_ray_pickable(bool p_ray_pickable) {
|
|
|
|
|
|
ray_pickable = p_ray_pickable;
|
|
ray_pickable = p_ray_pickable;
|
|
@@ -147,6 +185,8 @@ void CollisionObject::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject::shape_owner_clear_shapes);
|
|
ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject::shape_owner_clear_shapes);
|
|
ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject::shape_find_owner);
|
|
ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject::shape_find_owner);
|
|
|
|
|
|
|
|
+ ClassDB::bind_method(D_METHOD("_update_debug_shapes"), &CollisionObject::_update_debug_shapes);
|
|
|
|
+
|
|
BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
|
|
BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
|
|
|
|
|
|
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
|
|
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
|
|
@@ -196,6 +236,7 @@ void CollisionObject::shape_owner_set_disabled(uint32_t p_owner, bool p_disabled
|
|
PhysicsServer::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
|
|
PhysicsServer::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ _update_shape_data(p_owner);
|
|
}
|
|
}
|
|
|
|
|
|
bool CollisionObject::is_shape_owner_disabled(uint32_t p_owner) const {
|
|
bool CollisionObject::is_shape_owner_disabled(uint32_t p_owner) const {
|
|
@@ -235,6 +276,8 @@ void CollisionObject::shape_owner_set_transform(uint32_t p_owner, const Transfor
|
|
PhysicsServer::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform);
|
|
PhysicsServer::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ _update_shape_data(p_owner);
|
|
}
|
|
}
|
|
Transform CollisionObject::shape_owner_get_transform(uint32_t p_owner) const {
|
|
Transform CollisionObject::shape_owner_get_transform(uint32_t p_owner) const {
|
|
|
|
|
|
@@ -259,6 +302,7 @@ void CollisionObject::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape> &
|
|
ShapeData::ShapeBase s;
|
|
ShapeData::ShapeBase s;
|
|
s.index = total_subshapes;
|
|
s.index = total_subshapes;
|
|
s.shape = p_shape;
|
|
s.shape = p_shape;
|
|
|
|
+
|
|
if (area) {
|
|
if (area) {
|
|
PhysicsServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);
|
|
PhysicsServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled);
|
|
} else {
|
|
} else {
|
|
@@ -267,6 +311,8 @@ void CollisionObject::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape> &
|
|
sd.shapes.push_back(s);
|
|
sd.shapes.push_back(s);
|
|
|
|
|
|
total_subshapes++;
|
|
total_subshapes++;
|
|
|
|
+
|
|
|
|
+ _update_shape_data(p_owner);
|
|
}
|
|
}
|
|
int CollisionObject::shape_owner_get_shape_count(uint32_t p_owner) const {
|
|
int CollisionObject::shape_owner_get_shape_count(uint32_t p_owner) const {
|
|
|
|
|
|
@@ -294,13 +340,19 @@ void CollisionObject::shape_owner_remove_shape(uint32_t p_owner, int p_shape) {
|
|
ERR_FAIL_COND(!shapes.has(p_owner));
|
|
ERR_FAIL_COND(!shapes.has(p_owner));
|
|
ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
|
|
ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
|
|
|
|
|
|
- int index_to_remove = shapes[p_owner].shapes[p_shape].index;
|
|
|
|
|
|
+ const ShapeData::ShapeBase &s = shapes[p_owner].shapes[p_shape];
|
|
|
|
+ int index_to_remove = s.index;
|
|
|
|
+
|
|
if (area) {
|
|
if (area) {
|
|
PhysicsServer::get_singleton()->area_remove_shape(rid, index_to_remove);
|
|
PhysicsServer::get_singleton()->area_remove_shape(rid, index_to_remove);
|
|
} else {
|
|
} else {
|
|
PhysicsServer::get_singleton()->body_remove_shape(rid, index_to_remove);
|
|
PhysicsServer::get_singleton()->body_remove_shape(rid, index_to_remove);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (s.debug_shape) {
|
|
|
|
+ s.debug_shape->queue_delete();
|
|
|
|
+ }
|
|
|
|
+
|
|
shapes[p_owner].shapes.remove(p_shape);
|
|
shapes[p_owner].shapes.remove(p_shape);
|
|
|
|
|
|
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
|
|
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
|