You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-04 17:04:49 +00:00
Since the soft body meshes are always copied before simulation, the shared map never actually shared data with anything. This also makes it possible to create the mesh in local space the 2nd time it gets added to a space. This fixes the following 2 problems: * Inertia calculation becomes inaccurate when the vertices are far away from the origin. This triggered a harmless assert on 2nd insert. * The pressure calculations become inaccurate when the vertices are far away from the origin. Since we update the soft body position to the center of mass of all vertices at the end of every physics update, this problem lasted only for a single frame after reinserting and could cause a little jolt.
168 lines
6.1 KiB
C++
168 lines
6.1 KiB
C++
/**************************************************************************/
|
|
/* jolt_soft_body_3d.h */
|
|
/**************************************************************************/
|
|
/* This file is part of: */
|
|
/* GODOT ENGINE */
|
|
/* https://godotengine.org */
|
|
/**************************************************************************/
|
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
/* */
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
/* a copy of this software and associated documentation files (the */
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
/* the following conditions: */
|
|
/* */
|
|
/* The above copyright notice and this permission notice shall be */
|
|
/* included in all copies or substantial portions of the Software. */
|
|
/* */
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
/**************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#include "jolt_object_3d.h"
|
|
|
|
#include "servers/physics_3d/physics_server_3d.h"
|
|
|
|
#include "Jolt/Jolt.h"
|
|
|
|
#include "Jolt/Physics/SoftBody/SoftBodyCreationSettings.h"
|
|
#include "Jolt/Physics/SoftBody/SoftBodySharedSettings.h"
|
|
|
|
class JoltSpace3D;
|
|
|
|
class JoltSoftBody3D final : public JoltObject3D {
|
|
HashSet<int> pinned_vertices;
|
|
LocalVector<RID> exceptions;
|
|
LocalVector<Vector3> normals;
|
|
|
|
RID mesh;
|
|
LocalVector<int> mesh_to_physics;
|
|
|
|
JPH::SoftBodyCreationSettings *jolt_settings = new JPH::SoftBodyCreationSettings();
|
|
|
|
float mass = 0.0f;
|
|
float pressure = 0.0f;
|
|
float linear_damping = 0.01f;
|
|
float stiffness_coefficient = 0.5f;
|
|
float shrinking_factor = 0.0f;
|
|
|
|
int simulation_precision = 5;
|
|
|
|
virtual JPH::BroadPhaseLayer _get_broad_phase_layer() const override;
|
|
virtual JPH::ObjectLayer _get_object_layer() const override;
|
|
|
|
virtual void _space_changing() override;
|
|
virtual void _space_changed() override;
|
|
|
|
virtual void _add_to_space() override;
|
|
|
|
JPH::SoftBodySharedSettings *_create_shared_settings();
|
|
|
|
void _update_mass();
|
|
void _update_pressure();
|
|
void _update_damping();
|
|
void _update_simulation_precision();
|
|
void _update_group_filter();
|
|
|
|
void _try_rebuild();
|
|
|
|
void _mesh_changed();
|
|
void _simulation_precision_changed();
|
|
void _mass_changed();
|
|
void _pressure_changed();
|
|
void _damping_changed();
|
|
void _pins_changed();
|
|
void _vertices_changed();
|
|
void _exceptions_changed();
|
|
void _motion_changed();
|
|
|
|
public:
|
|
JoltSoftBody3D();
|
|
virtual ~JoltSoftBody3D() override;
|
|
|
|
void add_collision_exception(const RID &p_excepted_body);
|
|
void remove_collision_exception(const RID &p_excepted_body);
|
|
bool has_collision_exception(const RID &p_excepted_body) const;
|
|
|
|
const LocalVector<RID> &get_collision_exceptions() const { return exceptions; }
|
|
|
|
virtual bool can_interact_with(const JoltBody3D &p_other) const override;
|
|
virtual bool can_interact_with(const JoltSoftBody3D &p_other) const override;
|
|
virtual bool can_interact_with(const JoltArea3D &p_other) const override;
|
|
|
|
virtual bool reports_contacts() const override { return false; }
|
|
|
|
virtual Vector3 get_velocity_at_position(const Vector3 &p_position) const override;
|
|
|
|
void set_mesh(const RID &p_mesh);
|
|
|
|
bool is_pickable() const { return pickable; }
|
|
void set_pickable(bool p_enabled) { pickable = p_enabled; }
|
|
|
|
bool is_sleeping() const;
|
|
void set_is_sleeping(bool p_enabled);
|
|
|
|
bool is_sleep_allowed() const;
|
|
void set_is_sleep_allowed(bool p_enabled);
|
|
|
|
void put_to_sleep() { set_is_sleeping(true); }
|
|
void wake_up() { set_is_sleeping(false); }
|
|
|
|
int get_simulation_precision() const { return simulation_precision; }
|
|
void set_simulation_precision(int p_precision);
|
|
|
|
float get_mass() const { return mass; }
|
|
void set_mass(float p_mass);
|
|
|
|
float get_stiffness_coefficient() const;
|
|
void set_stiffness_coefficient(float p_coefficient);
|
|
|
|
float get_shrinking_factor() const;
|
|
void set_shrinking_factor(float p_shrinking_factor);
|
|
|
|
float get_pressure() const { return pressure; }
|
|
void set_pressure(float p_pressure);
|
|
|
|
float get_linear_damping() const { return linear_damping; }
|
|
void set_linear_damping(float p_damping);
|
|
|
|
float get_drag() const;
|
|
void set_drag(float p_drag);
|
|
|
|
Variant get_state(PhysicsServer3D::BodyState p_state) const;
|
|
void set_state(PhysicsServer3D::BodyState p_state, const Variant &p_value);
|
|
|
|
Transform3D get_transform() const;
|
|
void set_transform(const Transform3D &p_transform);
|
|
|
|
AABB get_bounds() const;
|
|
|
|
void update_rendering_server(PhysicsServer3DRenderingServerHandler *p_rendering_server_handler);
|
|
|
|
Vector3 get_vertex_position(int p_index);
|
|
void set_vertex_position(int p_index, const Vector3 &p_position);
|
|
|
|
void pin_vertex(int p_index);
|
|
void unpin_vertex(int p_index);
|
|
|
|
void unpin_all_vertices();
|
|
|
|
bool is_vertex_pinned(int p_index) const;
|
|
|
|
void apply_vertex_impulse(int p_index, const Vector3 &p_impulse);
|
|
void apply_vertex_force(int p_index, const Vector3 &p_force);
|
|
void apply_central_impulse(const Vector3 &p_impulse);
|
|
void apply_central_force(const Vector3 &p_force);
|
|
};
|