Skip to content

Commit

Permalink
Fix crash. Update fluid debug rendering to be internal. (#63)
Browse files Browse the repository at this point in the history
- Fixes #62
  • Loading branch information
Ughuuu authored Apr 14, 2024
1 parent b50fe74 commit a592b92
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 62 deletions.
10 changes: 10 additions & 0 deletions bin/addons/godot-rapier2d/Fluid2DCircle.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@tool
extends Fluid2D

@export var radius := 10:
set(value):
if radius != value:
radius = value
points = create_circle_points(radius)
get:
return radius
17 changes: 17 additions & 0 deletions bin/addons/godot-rapier2d/Fluid2DRectangle.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@tool
extends Fluid2D

@export var height := 10:
set(value):
if height != value:
height = value
points = create_rectangle_points(width, height)
get:
return height
@export var width := 10:
set(value):
if width != value:
width = value
points = create_rectangle_points(width, height)
get:
return width
40 changes: 0 additions & 40 deletions bin/addons/godot-rapier2d/Fluid2DRenderer.gd

This file was deleted.

135 changes: 120 additions & 15 deletions src/fluids/fluid_2d.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
#include "fluid_2d.h"
#include "../servers/rapier_physics_server_2d.h"
#include "../servers/rapier_project_settings.h"
#include <godot_cpp/classes/editor_settings.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/world2d.hpp>

RapierPhysicsServer2D *_get_rapier_physics_server() {
static auto *physics_server = dynamic_cast<RapierPhysicsServer2D *>(PhysicsServer2D::get_singleton());
ERR_FAIL_NULL_V(physics_server, nullptr);

auto *physics_server = dynamic_cast<RapierPhysicsServer2D *>(PhysicsServer2D::get_singleton());
if (!physics_server) {
ERR_PRINT_ONCE("Fluid2D node requires Rapier2D Physics Engine. Disabling it.");
}
return physics_server;
}

Expand All @@ -14,37 +20,92 @@ real_t Fluid2D::get_density() const {
}

void Fluid2D::set_density(real_t p_density) {
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return;
}
if (density != p_density) {
density = p_density;
_get_rapier_physics_server()->fluid_set_density(rid, density);
rapier_physics_server->fluid_set_density(rid, density);
}
}

PackedVector2Array Fluid2D::get_accelerations() const {
return _get_rapier_physics_server()->fluid_get_accelerations(rid);
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return PackedVector2Array();
}
return rapier_physics_server->fluid_get_accelerations(rid);
}
PackedVector2Array Fluid2D::get_velocities() const {
return _get_rapier_physics_server()->fluid_get_velocities(rid);
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return PackedVector2Array();
}
return rapier_physics_server->fluid_get_velocities(rid);
}
PackedVector2Array Fluid2D::get_points() const {
return _get_rapier_physics_server()->fluid_get_points(rid);
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return PackedVector2Array();
}
auto new_points = rapier_physics_server->fluid_get_points(rid);

Transform2D gl_transform = get_global_transform();
for (int i = 0; i < new_points.size(); i++) {
new_points[i] = gl_transform.xform_inv(new_points[i]);
}
return new_points;
}
PackedVector2Array Fluid2D::create_rectangle_points(int width, int height) {
PackedVector2Array new_points;
new_points.resize(width * height);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
new_points[i + j * width] = Vector2(i * radius * 2, j * radius * 2);
}
}
return new_points;
}
PackedVector2Array Fluid2D::create_circle_points(int p_radius) {
PackedVector2Array new_points;
for (float i = -p_radius; i <= p_radius; i += 1) {
for (float j = -p_radius; j <= p_radius; j += 1) {
float x = i * radius * 2;
float y = j * radius * 2;
if (Math::sqrt(i * i + j * j) <= p_radius) {
new_points.append(Vector2(x, y));
}
}
}
return new_points;
}

void Fluid2D::set_points(PackedVector2Array p_points) {
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return;
}
points = p_points;
Transform2D gl_transform = get_global_transform();
for (int i = 0; i < p_points.size(); i++) {
p_points[i] = gl_transform.xform(p_points[i]);
}
_get_rapier_physics_server()->fluid_set_points(rid, p_points);
rapier_physics_server->fluid_set_points(rid, p_points);
queue_redraw();
}

RID Fluid2D::get_rid() const {
return rid;
}

void Fluid2D::set_effects(const TypedArray<FluidEffect2D> &p_effects) {
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return;
}
effects = p_effects;
_get_rapier_physics_server()->fluid_set_effects(rid, effects);
rapier_physics_server->fluid_set_effects(rid, effects);
}

TypedArray<FluidEffect2D> Fluid2D::get_effects() const {
Expand All @@ -71,29 +132,73 @@ void Fluid2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "effects", PROPERTY_HINT_TYPE_STRING,
String::num(Variant::OBJECT) + "/" + String::num(PROPERTY_HINT_RESOURCE_TYPE) + ":FluidEffect2D"),
"set_effects", "get_effects");

ClassDB::bind_method(D_METHOD("create_rectangle_points", "width", "height"), &Fluid2D::create_rectangle_points);
ClassDB::bind_method(D_METHOD("create_circle_points", "radius"), &Fluid2D::create_circle_points);
}

Fluid2D::Fluid2D() {
rid = _get_rapier_physics_server()->fluid_create();
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return;
}
rid = rapier_physics_server->fluid_create();
radius = RapierProjectSettings::get_fluid_particle_radius();
color = ProjectSettings::get_singleton()->get("debug/shapes/navigation/geometry_face_color");

debug_draw = RapierProjectSettings::get_fluid_draw_debug();
if (Engine::get_singleton()->is_editor_hint()) {
debug_draw = true;
}
if (debug_draw) {
set_process(true);
set_notify_transform(true);
}
}

Fluid2D::~Fluid2D() {
_get_rapier_physics_server()->free_rid(rid);
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return;
}
rapier_physics_server->free_rid(rid);
}

void Fluid2D::_notification(int p_what) {
RapierPhysicsServer2D *rapier_physics_server = _get_rapier_physics_server();
if (!rapier_physics_server) {
return;
}
switch (p_what) {
case NOTIFICATION_PROCESS: {
if (debug_draw) {
points = get_points();
queue_redraw();
}
} break;
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_WORLD_2D_CHANGED:
case NOTIFICATION_TRANSFORM_CHANGED: {
case NOTIFICATION_TRANSFORM_CHANGED:
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
RID space = get_world_2d()->get_space();
_get_rapier_physics_server()->fluid_set_space(rid, space);
rapier_physics_server->fluid_set_space(rid, space);
set_points(points);
//set_effects(effects);
if (debug_draw) {
queue_redraw();
}
} break;

case NOTIFICATION_EXIT_TREE: {
_get_rapier_physics_server()->fluid_set_space(rid, RID());
rapier_physics_server->fluid_set_space(rid, RID());
} break;
case NOTIFICATION_DRAW: {
if (debug_draw) {
points = get_points();
for (int i = 0; i < points.size(); i++) {
draw_rect(Rect2(points[i] - Vector2(radius / 2.0, radius / 2.0), Vector2(radius, radius)), color);
}
}
} break;
}
}
5 changes: 5 additions & 0 deletions src/fluids/fluid_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ class Fluid2D : public Node2D {

private:
RID rid;
real_t radius;
bool enabled = true;
bool debug_draw = false;
real_t density = 1.0;
Color color;
TypedArray<FluidEffect2D> effects;

PackedVector2Array points;
Expand All @@ -32,6 +35,8 @@ class Fluid2D : public Node2D {
PackedVector2Array get_accelerations() const;
PackedVector2Array get_velocities() const;
PackedVector2Array get_points() const;
PackedVector2Array create_rectangle_points(int width, int height);
PackedVector2Array create_circle_points(int p_radius);
void set_points(PackedVector2Array p_points);

void set_effects(const TypedArray<FluidEffect2D> &p_effects);
Expand Down
1 change: 0 additions & 1 deletion src/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ void initialize_rapier_2d_module(ModuleInitializationLevel p_level) {
ClassDB::register_class<FluidEffect2DViscosityArtificial>();
ClassDB::register_class<FluidEffect2DViscosityDFSPH>();
ClassDB::register_class<FluidEffect2DViscosityXSPH>();

ClassDB::register_class<Fluid2D>();
} break;
default: {
Expand Down
18 changes: 12 additions & 6 deletions src/servers/rapier_project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ constexpr char FLUID_GRAVITY_DIR[] = "physics/rapier_2d/fluid/fluid_gravity_dir"
constexpr char FLUID_GRAVITY_VALUE[] = "physics/rapier_2d/fluid/fluid_gravity_value";
constexpr char FLUID_PARTICLE_RADIUS[] = "physics/rapier_2d/fluid/fluid_particle_radius";
constexpr char FLUID_SMOOTHING_FACTOR[] = "physics/rapier_2d/fluid/fluid_smoothing_factor";
constexpr char FLUID_DRAW_DEBUG[] = "physics/rapier_2d/fluid/fluid_draw_debug";

void register_setting(
const String &p_name,
Expand Down Expand Up @@ -80,16 +81,17 @@ void RapierProjectSettings::register_settings() {
register_setting_ranged(SOLVER_DAMPING_RATIO, 1.0, U"0.00001,1,0.00001,suffix:%");
register_setting_ranged(SOLVER_JOINT_ERP, 1.0, U"0.00001,1,0.00001,suffix:%");
register_setting_ranged(SOLVER_JOINT_DAMPING_RATIO, 1.0, U"0.0001,1,0.00001,suffix:%");
register_setting_ranged(SOLVER_ALLOWED_LINEAR_ERROR, 0.001, U"0,1,0.00001,suffix:m");
register_setting_ranged(SOLVER_PREDICTION_DISTANCE, 0.002, U"0,1,0.00001,suffix:m");
register_setting_ranged(SOLVER_ALLOWED_LINEAR_ERROR, 0.001, U"0,1,0.00001");
register_setting_ranged(SOLVER_PREDICTION_DISTANCE, 0.002, U"0,1,0.00001");
register_setting_ranged(SOLVER_NUM_INTERNAL_PGS_ITERATIONS, 1, U"1,4,or_greater");
register_setting_ranged(SOLVER_NUM_ADDITIONAL_FRICTION_ITERATIONS, 4, U"1,16,or_greater");
register_setting_ranged(SOLVER_NUM_ITERATIONS, 4, U"1,16,or_greater");
register_setting_ranged(SOLVER_MAX_CCD_SUBSTEPS, 1, U"1,16,or_greater");
register_setting_plain(FLUID_GRAVITY_DIR, Vector2(0.0, 1.0), "");
register_setting_plain(FLUID_GRAVITY_VALUE, 980.0, "");
register_setting_ranged(FLUID_PARTICLE_RADIUS, 10.0, U"0,100,0.00001,suffix:m");
register_setting_ranged(FLUID_SMOOTHING_FACTOR, 2.0, U"0,10,0.00001,suffix:%");
register_setting_plain(FLUID_GRAVITY_DIR, Vector2(0.0, 1.0));
register_setting_plain(FLUID_GRAVITY_VALUE, 980.0);
register_setting_ranged(FLUID_PARTICLE_RADIUS, 5.0, U"0,100,0.00001", true);
register_setting_ranged(FLUID_SMOOTHING_FACTOR, 2.0, U"0,10,0.00001,suffix:%", true);
register_setting_plain(FLUID_DRAW_DEBUG, true);
}

template <typename TType>
Expand Down Expand Up @@ -157,3 +159,7 @@ double RapierProjectSettings::get_fluid_particle_radius() {
double RapierProjectSettings::get_fluid_smoothing_factor() {
return get_setting<double>(FLUID_SMOOTHING_FACTOR);
}

bool RapierProjectSettings::get_fluid_draw_debug() {
return get_setting<bool>(FLUID_DRAW_DEBUG);
}
1 change: 1 addition & 0 deletions src/servers/rapier_project_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class RapierProjectSettings {
static double get_fluid_gravity_value();
static double get_fluid_smoothing_factor();
static double get_fluid_particle_radius();
static bool get_fluid_draw_debug();
};

#endif // RAPIER_PROJECT_SETTINGS_H

0 comments on commit a592b92

Please sign in to comment.