Fixed Softbody pin point
This commit is contained in:
parent
07129deaeb
commit
45160f0c0d
|
@ -98,7 +98,7 @@ SoftBody::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
|
||||||
point_index = obj_tocopy.point_index;
|
point_index = obj_tocopy.point_index;
|
||||||
spatial_attachment_path = obj_tocopy.spatial_attachment_path;
|
spatial_attachment_path = obj_tocopy.spatial_attachment_path;
|
||||||
spatial_attachment = obj_tocopy.spatial_attachment;
|
spatial_attachment = obj_tocopy.spatial_attachment;
|
||||||
vertex_offset_transform = obj_tocopy.vertex_offset_transform;
|
offset = obj_tocopy.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftBody::_update_pickable() {
|
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) {
|
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::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::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) {
|
if ("spatial_attachment_path" == p_what) {
|
||||||
PoolVector<PinnedPoint>::Write w = pinned_points_indices.write();
|
PoolVector<PinnedPoint>::Write w = pinned_points_indices.write();
|
||||||
pin_point(w[p_item].point_index, true, p_value);
|
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 {
|
} else {
|
||||||
return false;
|
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;
|
r_ret = r[p_item].point_index;
|
||||||
} else if ("spatial_attachment_path" == p_what) {
|
} else if ("spatial_attachment_path" == p_what) {
|
||||||
r_ret = r[p_item].spatial_attachment_path;
|
r_ret = r[p_item].spatial_attachment_path;
|
||||||
|
} else if ("offset" == p_what) {
|
||||||
|
r_ret = r[p_item].offset;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +252,6 @@ void SoftBody::_notification(int p_what) {
|
||||||
|
|
||||||
RID space = get_world()->get_space();
|
RID space = get_world()->get_space();
|
||||||
PhysicsServer::get_singleton()->soft_body_set_space(physics_rid, 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();
|
update_physics_server();
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_READY: {
|
case NOTIFICATION_READY: {
|
||||||
|
@ -255,20 +261,30 @@ void SoftBody::_notification(int p_what) {
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
|
|
||||||
if (!simulation_started) {
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
|
return;
|
||||||
|
|
||||||
PhysicsServer::get_singleton()->soft_body_set_transform(physics_rid, get_global_transform());
|
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();
|
_update_cache_pin_points_datas();
|
||||||
// Submit bone attachment
|
// Submit bone attachment
|
||||||
const int pinned_points_indices_size = pinned_points_indices.size();
|
const int pinned_points_indices_size = pinned_points_indices.size();
|
||||||
PoolVector<PinnedPoint>::Read r = pinned_points_indices.read();
|
PoolVector<PinnedPoint>::Read r = pinned_points_indices.read();
|
||||||
for (int i = 0; i < pinned_points_indices_size; ++i) {
|
for (int i = 0; i < pinned_points_indices_size; ++i) {
|
||||||
if (!r[i].spatial_attachment) {
|
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, r[i].spatial_attachment->get_global_transform().xform(r[i].offset));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -408,8 +424,15 @@ void SoftBody::_draw_soft_mesh() {
|
||||||
|
|
||||||
void SoftBody::update_physics_server() {
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (get_mesh().is_valid()) {
|
if (get_mesh().is_valid()) {
|
||||||
|
|
||||||
|
@ -651,6 +674,8 @@ SoftBody::SoftBody() :
|
||||||
pinned_points_cache_dirty(true) {
|
pinned_points_cache_dirty(true) {
|
||||||
|
|
||||||
PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
|
PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
|
||||||
|
//set_notify_transform(true);
|
||||||
|
set_physics_process_internal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftBody::~SoftBody() {
|
SoftBody::~SoftBody() {
|
||||||
|
@ -664,8 +689,14 @@ void SoftBody::reset_softbody_pin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftBody::_make_cache_dirty() {
|
||||||
|
pinned_points_cache_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
void SoftBody::_update_cache_pin_points_datas() {
|
void SoftBody::_update_cache_pin_points_datas() {
|
||||||
if (pinned_points_cache_dirty) {
|
if (!pinned_points_cache_dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
pinned_points_cache_dirty = false;
|
pinned_points_cache_dirty = false;
|
||||||
|
|
||||||
PoolVector<PinnedPoint>::Write w = pinned_points_indices.write();
|
PoolVector<PinnedPoint>::Write w = pinned_points_indices.write();
|
||||||
|
@ -673,21 +704,9 @@ void SoftBody::_update_cache_pin_points_datas() {
|
||||||
|
|
||||||
if (!w[i].spatial_attachment_path.is_empty()) {
|
if (!w[i].spatial_attachment_path.is_empty()) {
|
||||||
w[i].spatial_attachment = Object::cast_to<Spatial>(get_node(w[i].spatial_attachment_path));
|
w[i].spatial_attachment = Object::cast_to<Spatial>(get_node(w[i].spatial_attachment_path));
|
||||||
if (w[i].spatial_attachment) {
|
|
||||||
|
|
||||||
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.");
|
|
||||||
}
|
}
|
||||||
}
|
if (!w[i].spatial_attachment) {
|
||||||
// Local transform relative to Soft body
|
ERR_PRINT("Spatial node not defined in the pinned point, Softbody undefined behaviour!");
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,15 +718,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) {
|
void SoftBody::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) {
|
||||||
SoftBody::PinnedPoint *pinned_point;
|
SoftBody::PinnedPoint *pinned_point;
|
||||||
if (-1 == _get_pinned_point(p_point_index, pinned_point)) {
|
if (-1 == _get_pinned_point(p_point_index, pinned_point)) {
|
||||||
|
|
||||||
// Create new
|
// Create new
|
||||||
PinnedPoint pp;
|
PinnedPoint pp;
|
||||||
pp.point_index = p_point_index;
|
pp.point_index = p_point_index;
|
||||||
pp.spatial_attachment_path = p_spatial_attachment_path;
|
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);
|
pinned_points_indices.push_back(pp);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Update
|
|
||||||
pinned_point->point_index = p_point_index;
|
pinned_point->point_index = p_point_index;
|
||||||
pinned_point->spatial_attachment_path = p_spatial_attachment_path;
|
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;
|
int point_index;
|
||||||
NodePath spatial_attachment_path;
|
NodePath spatial_attachment_path;
|
||||||
Spatial *spatial_attachment; // Cache
|
Spatial *spatial_attachment; // Cache
|
||||||
/// This is the offset from the soft body to point or attachment to point
|
Vector3 offset;
|
||||||
/// Depend if the spatial_attachment_node is NULL or not
|
|
||||||
Transform vertex_offset_transform; // Cache
|
|
||||||
|
|
||||||
PinnedPoint();
|
PinnedPoint();
|
||||||
PinnedPoint(const PinnedPoint &obj_tocopy);
|
PinnedPoint(const PinnedPoint &obj_tocopy);
|
||||||
|
@ -186,6 +184,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset_softbody_pin();
|
void reset_softbody_pin();
|
||||||
|
void _make_cache_dirty();
|
||||||
void _update_cache_pin_points_datas();
|
void _update_cache_pin_points_datas();
|
||||||
void _pin_point_on_physics_server(int p_point_index, bool pin);
|
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);
|
void _add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path);
|
||||||
|
|
Loading…
Reference in New Issue