diff options
Diffstat (limited to 'scene/3d')
-rw-r--r-- | scene/3d/camera.cpp | 18 | ||||
-rw-r--r-- | scene/3d/camera.h | 3 | ||||
-rw-r--r-- | scene/3d/soft_body.cpp | 114 | ||||
-rw-r--r-- | scene/3d/soft_body.h | 5 | ||||
-rw-r--r-- | scene/3d/visual_instance.cpp | 16 | ||||
-rw-r--r-- | scene/3d/visual_instance.h | 3 |
6 files changed, 116 insertions, 43 deletions
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 9a2046991b..0fe427d5fc 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -468,6 +468,10 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode); ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking); ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera::get_doppler_tracking); + + ClassDB::bind_method(D_METHOD("set_cull_mask_bit", "layer", "enable"), &Camera::set_cull_mask_bit); + ClassDB::bind_method(D_METHOD("get_cull_mask_bit", "layer"), &Camera::get_cull_mask_bit); + //ClassDB::bind_method(D_METHOD("_camera_make_current"),&Camera::_camera_make_current ); ADD_PROPERTY(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"), "set_keep_aspect_mode", "get_keep_aspect_mode"); @@ -550,6 +554,20 @@ uint32_t Camera::get_cull_mask() const { return layers; } +void Camera::set_cull_mask_bit(int p_layer, bool p_enable) { + ERR_FAIL_INDEX(p_layer, 32); + if (p_enable) { + set_cull_mask(layers | (1 << p_layer)); + } else { + set_cull_mask(layers & (~(1 << p_layer))); + } +} + +bool Camera::get_cull_mask_bit(int p_layer) const { + ERR_FAIL_INDEX_V(p_layer, 32, false); + return (layers & (1 << p_layer)); +} + Vector<Plane> Camera::get_frustum() const { ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>()); diff --git a/scene/3d/camera.h b/scene/3d/camera.h index 1b506e0c4f..97705d8ae0 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -142,6 +142,9 @@ public: void set_cull_mask(uint32_t p_layers); uint32_t get_cull_mask() const; + void set_cull_mask_bit(int p_layer, bool p_enable); + bool get_cull_mask_bit(int p_layer) const; + virtual Vector<Plane> get_frustum() const; void set_environment(const Ref<Environment> &p_environment); diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index 8498dc34c0..4ab7013707 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -98,7 +98,7 @@ SoftBody::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) { point_index = obj_tocopy.point_index; spatial_attachment_path = obj_tocopy.spatial_attachment_path; spatial_attachment = obj_tocopy.spatial_attachment; - vertex_offset_transform = obj_tocopy.vertex_offset_transform; + offset = obj_tocopy.offset; } void SoftBody::_update_pickable() { @@ -164,6 +164,7 @@ void SoftBody::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < pinned_points_indices_size; ++i) { p_list->push_back(PropertyInfo(Variant::INT, "attachments/" + itos(i) + "/point_index")); p_list->push_back(PropertyInfo(Variant::NODE_PATH, "attachments/" + itos(i) + "/spatial_attachment_path")); + p_list->push_back(PropertyInfo(Variant::VECTOR3, "attachments/" + itos(i) + "/offset")); } } @@ -204,6 +205,10 @@ bool SoftBody::_set_property_pinned_points_attachment(int p_item, const String & if ("spatial_attachment_path" == p_what) { PoolVector<PinnedPoint>::Write w = pinned_points_indices.write(); pin_point(w[p_item].point_index, true, p_value); + _make_cache_dirty(); + } else if ("offset" == p_what) { + PoolVector<PinnedPoint>::Write w = pinned_points_indices.write(); + w[p_item].offset = p_value; } else { return false; } @@ -221,6 +226,8 @@ bool SoftBody::_get_property_pinned_points(int p_item, const String &p_what, Var r_ret = r[p_item].point_index; } else if ("spatial_attachment_path" == p_what) { r_ret = r[p_item].spatial_attachment_path; + } else if ("offset" == p_what) { + r_ret = r[p_item].offset; } else { return false; } @@ -245,7 +252,6 @@ void SoftBody::_notification(int p_what) { RID space = get_world()->get_space(); PhysicsServer::get_singleton()->soft_body_set_space(physics_rid, space); - PhysicsServer::get_singleton()->soft_body_set_transform(physics_rid, get_global_transform()); update_physics_server(); } break; case NOTIFICATION_READY: { @@ -255,20 +261,30 @@ void SoftBody::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (!simulation_started) { - PhysicsServer::get_singleton()->soft_body_set_transform(physics_rid, get_global_transform()); - - _update_cache_pin_points_datas(); - // Submit bone attachment - const int pinned_points_indices_size = pinned_points_indices.size(); - PoolVector<PinnedPoint>::Read r = pinned_points_indices.read(); - for (int i = 0; i < pinned_points_indices_size; ++i) { - if (!r[i].spatial_attachment) { - // Use soft body position to update the point position - PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, (get_global_transform() * r[i].vertex_offset_transform).origin); - } else { - PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, (r[i].spatial_attachment->get_global_transform() * r[i].vertex_offset_transform).origin); - } + if (Engine::get_singleton()->is_editor_hint()) + return; + + PhysicsServer::get_singleton()->soft_body_set_transform(physics_rid, get_global_transform()); + + set_notify_transform(false); + // Required to be top level with Transform at center of world in order to modify VisualServer only to support custom Transform + set_as_toplevel(true); + set_transform(Transform()); + set_notify_transform(true); + + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + + if (!simulation_started) + return; + + _update_cache_pin_points_datas(); + // Submit bone attachment + const int pinned_points_indices_size = pinned_points_indices.size(); + PoolVector<PinnedPoint>::Read r = pinned_points_indices.read(); + for (int i = 0; i < pinned_points_indices_size; ++i) { + if (r[i].spatial_attachment) { + PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, r[i].spatial_attachment->get_global_transform().xform(r[i].offset)); } } } break; @@ -408,8 +424,15 @@ void SoftBody::_draw_soft_mesh() { void SoftBody::update_physics_server() { - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint()) { + + if (get_mesh().is_valid()) + PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()); + else + PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, NULL); + return; + } if (get_mesh().is_valid()) { @@ -430,6 +453,9 @@ void SoftBody::become_mesh_owner() { if (!mesh_owner) { mesh_owner = true; + Vector<Ref<Material> > copy_materials; + copy_materials.append_array(materials); + ERR_FAIL_COND(!mesh->get_surface_count()); // Get current mesh array and create new mesh array with necessary flag for softbody @@ -443,11 +469,10 @@ void SoftBody::become_mesh_owner() { Ref<ArrayMesh> soft_mesh; soft_mesh.instance(); soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_format); + soft_mesh->surface_set_material(0, mesh->surface_get_material(0)); set_mesh(soft_mesh); - Vector<Ref<Material> > copy_materials; - copy_materials.append_array(materials); for (int i = copy_materials.size() - 1; 0 <= i; --i) { set_surface_material(i, copy_materials[i]); } @@ -651,6 +676,8 @@ SoftBody::SoftBody() : pinned_points_cache_dirty(true) { PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id()); + //set_notify_transform(true); + set_physics_process_internal(true); } SoftBody::~SoftBody() { @@ -664,30 +691,24 @@ void SoftBody::reset_softbody_pin() { } } -void SoftBody::_update_cache_pin_points_datas() { - if (pinned_points_cache_dirty) { - pinned_points_cache_dirty = false; +void SoftBody::_make_cache_dirty() { + pinned_points_cache_dirty = true; +} - PoolVector<PinnedPoint>::Write w = pinned_points_indices.write(); - for (int i = pinned_points_indices.size() - 1; 0 <= i; --i) { +void SoftBody::_update_cache_pin_points_datas() { + if (!pinned_points_cache_dirty) + return; - if (!w[i].spatial_attachment_path.is_empty()) { - w[i].spatial_attachment = Object::cast_to<Spatial>(get_node(w[i].spatial_attachment_path)); - if (w[i].spatial_attachment) { + pinned_points_cache_dirty = false; - Transform point_global_transform(get_global_transform()); - point_global_transform.translate(PhysicsServer::get_singleton()->soft_body_get_point_offset(physics_rid, w[i].point_index)); + PoolVector<PinnedPoint>::Write w = pinned_points_indices.write(); + for (int i = pinned_points_indices.size() - 1; 0 <= i; --i) { - // Local transform relative to spatial attachment node - w[i].vertex_offset_transform = w[i].spatial_attachment->get_global_transform().affine_inverse() * point_global_transform; - continue; - } else { - ERR_PRINTS("The node with path: " + String(w[i].spatial_attachment_path) + " was not found or is not a spatial node."); - } - } - // Local transform relative to Soft body - w[i].vertex_offset_transform.origin = PhysicsServer::get_singleton()->soft_body_get_point_offset(physics_rid, w[i].point_index); - w[i].vertex_offset_transform.basis = Basis(); + if (!w[i].spatial_attachment_path.is_empty()) { + w[i].spatial_attachment = Object::cast_to<Spatial>(get_node(w[i].spatial_attachment_path)); + } + if (!w[i].spatial_attachment) { + ERR_PRINT("Spatial node not defined in the pinned point, Softbody undefined behaviour!"); } } } @@ -699,15 +720,28 @@ void SoftBody::_pin_point_on_physics_server(int p_point_index, bool pin) { void SoftBody::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) { SoftBody::PinnedPoint *pinned_point; if (-1 == _get_pinned_point(p_point_index, pinned_point)) { + // Create new PinnedPoint pp; pp.point_index = p_point_index; pp.spatial_attachment_path = p_spatial_attachment_path; + + if (!p_spatial_attachment_path.is_empty() && has_node(p_spatial_attachment_path)) { + pp.spatial_attachment = Object::cast_to<Spatial>(get_node(p_spatial_attachment_path)); + pp.offset = (pp.spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer::get_singleton()->soft_body_get_point_global_position(physics_rid, pp.point_index)); + } + pinned_points_indices.push_back(pp); + } else { - // Update + pinned_point->point_index = p_point_index; pinned_point->spatial_attachment_path = p_spatial_attachment_path; + + if (!p_spatial_attachment_path.is_empty() && has_node(p_spatial_attachment_path)) { + pinned_point->spatial_attachment = Object::cast_to<Spatial>(get_node(p_spatial_attachment_path)); + pinned_point->offset = (pinned_point->spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer::get_singleton()->soft_body_get_point_global_position(physics_rid, pinned_point->point_index)); + } } } diff --git a/scene/3d/soft_body.h b/scene/3d/soft_body.h index f44f337698..6cf19ef8c4 100644 --- a/scene/3d/soft_body.h +++ b/scene/3d/soft_body.h @@ -72,9 +72,7 @@ public: int point_index; NodePath spatial_attachment_path; Spatial *spatial_attachment; // Cache - /// This is the offset from the soft body to point or attachment to point - /// Depend if the spatial_attachment_node is NULL or not - Transform vertex_offset_transform; // Cache + Vector3 offset; PinnedPoint(); PinnedPoint(const PinnedPoint &obj_tocopy); @@ -186,6 +184,7 @@ public: private: void reset_softbody_pin(); + void _make_cache_dirty(); void _update_cache_pin_points_datas(); void _pin_point_on_physics_server(int p_point_index, bool pin); void _add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path); diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 00541a7d8a..767518dc83 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -105,12 +105,28 @@ uint32_t VisualInstance::get_layer_mask() const { return layers; } +void VisualInstance::set_layer_mask_bit(int p_layer, bool p_enable) { + ERR_FAIL_INDEX(p_layer, 32); + if (p_enable) { + set_layer_mask(layers | (1 << p_layer)); + } else { + set_layer_mask(layers & (~(1 << p_layer))); + } +} + +bool VisualInstance::get_layer_mask_bit(int p_layer) const { + ERR_FAIL_INDEX_V(p_layer, 32, false); + return (layers & (1 << p_layer)); +} + void VisualInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance::_get_visual_instance_rid); ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance::set_base); ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &VisualInstance::set_layer_mask); ClassDB::bind_method(D_METHOD("get_layer_mask"), &VisualInstance::get_layer_mask); + ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "layer", "enabled"), &VisualInstance::set_layer_mask_bit); + ClassDB::bind_method(D_METHOD("get_layer_mask_bit", "layer"), &VisualInstance::get_layer_mask_bit); ClassDB::bind_method(D_METHOD("get_transformed_aabb"), &VisualInstance::get_transformed_aabb); diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index 8458a343b2..9249bc04ce 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -73,6 +73,9 @@ public: void set_layer_mask(uint32_t p_mask); uint32_t get_layer_mask() const; + void set_layer_mask_bit(int p_layer, bool p_enable); + bool get_layer_mask_bit(int p_layer) const; + VisualInstance(); ~VisualInstance(); }; |