Merge pull request #20550 from AndreaCatania/soft_fix
Soft Body - Pin Point fix, Material fix
This commit is contained in:
commit
3f01f40e91
2 changed files with 75 additions and 42 deletions
|
@ -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());
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
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) {
|
||||
// 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);
|
||||
}
|
||||
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::_make_cache_dirty() {
|
||||
pinned_points_cache_dirty = true;
|
||||
}
|
||||
|
||||
void SoftBody::_update_cache_pin_points_datas() {
|
||||
if (pinned_points_cache_dirty) {
|
||||
pinned_points_cache_dirty = false;
|
||||
if (!pinned_points_cache_dirty)
|
||||
return;
|
||||
|
||||
PoolVector<PinnedPoint>::Write w = pinned_points_indices.write();
|
||||
for (int i = pinned_points_indices.size() - 1; 0 <= i; --i) {
|
||||
pinned_points_cache_dirty = false;
|
||||
|
||||
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) {
|
||||
PoolVector<PinnedPoint>::Write w = pinned_points_indices.write();
|
||||
for (int i = pinned_points_indices.size() - 1; 0 <= i; --i) {
|
||||
|
||||
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));
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue