Repository: godotengine/godot
File: scene/3d/soft_body_3d.cpp (C++)

Code before:
}

real_t SoftBody3D::get_drag_coefficient() {
	return PhysicsServer3D::get_singleton()->soft_body_get_drag_coefficient(physics_rid);
}

void SoftBody3D::set_drag_coefficient(real_t p_drag_coefficient) {
	PhysicsServer3D::get_singleton()->soft_body_set_drag_coefficient(physics_rid, p_drag_coefficient);
}

Vector3 SoftBody3D::get_point_transform(int p_point_index) {
	return PhysicsServer3D::get_singleton()->soft_body_get_point_global_position(physics_rid, p_point_index);
}

void SoftBody3D::pin_point_toggle(int p_point_index) {
	pin_point(p_point_index, !(-1 != _has_pinned_point(p_point_index)));
}

void SoftBody3D::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path) {
	_pin_point_on_physics_server(p_point_index, pin);
	if (pin) {
		_add_pinned_point(p_point_index, p_spatial_attachment_path);
	} else {
		_remove_pinned_point(p_point_index);
	}
}

void SoftBody3D::_pin_point_deferred(int p_point_index, bool pin, const NodePath p_spatial_attachment_path) {
	pin_point(p_point_index, pin, p_spatial_attachment_path);
	_make_cache_dirty();
}

bool SoftBody3D::is_point_pinned(int p_point_index) const {
	return -1 != _has_pinned_point(p_point_index);
}

void SoftBody3D::set_ray_pickable(bool p_ray_pickable) {
	ray_pickable = p_ray_pickable;
	_update_pickable();
}

bool SoftBody3D::is_ray_pickable() const {
	return ray_pickable;
}

SoftBody3D::SoftBody3D() :
		physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()) {
	rendering_server_handler = memnew(SoftBodyRenderingServerHandler);
	PhysicsServer3D::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
}


Review comment (suggestion):
This should validate that the `p_insert_at` range is valid, i.e. `>= -1` and `< pinned_points.size()`. Otherwise this will lead to hard-to-understand errors surfaced in CowData if users pass invalid values.

Code after:

real_t SoftBody3D::get_damping_coefficient() {
	return PhysicsServer3D::get_singleton()->soft_body_get_damping_coefficient(physics_rid);
}

void SoftBody3D::set_damping_coefficient(real_t p_damping_coefficient) {
	PhysicsServer3D::get_singleton()->soft_body_set_damping_coefficient(physics_rid, p_damping_coefficient);
}

real_t SoftBody3D::get_drag_coefficient() {
	return PhysicsServer3D::get_singleton()->soft_body_get_drag_coefficient(physics_rid);
}

void SoftBody3D::set_drag_coefficient(real_t p_drag_coefficient) {
	PhysicsServer3D::get_singleton()->soft_body_set_drag_coefficient(physics_rid, p_drag_coefficient);
}

Vector3 SoftBody3D::get_point_transform(int p_point_index) {
	return PhysicsServer3D::get_singleton()->soft_body_get_point_global_position(physics_rid, p_point_index);
}

void SoftBody3D::pin_point_toggle(int p_point_index) {
	pin_point(p_point_index, !(-1 != _has_pinned_point(p_point_index)));
}

void SoftBody3D::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path, int p_insert_at) {
	ERR_FAIL_COND_MSG(p_insert_at < -1 || p_insert_at >= pinned_points.size(), "Invalid index for pin point insertion position.");
	_pin_point_on_physics_server(p_point_index, pin);
	if (pin) {
		_add_pinned_point(p_point_index, p_spatial_attachment_path, p_insert_at);
	} else {
		_remove_pinned_point(p_point_index);
	}
}

void SoftBody3D::_pin_point_deferred(int p_point_index, bool pin, const NodePath p_spatial_attachment_path) {
	pin_point(p_point_index, pin, p_spatial_attachment_path);
	_make_cache_dirty();
}

bool SoftBody3D::is_point_pinned(int p_point_index) const {
	return -1 != _has_pinned_point(p_point_index);
}

void SoftBody3D::set_ray_pickable(bool p_ray_pickable) {
	ray_pickable = p_ray_pickable;
	_update_pickable();
}

bool SoftBody3D::is_ray_pickable() const {
	return ray_pickable;