@@ -52,15 +52,19 @@ void SoftBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) {
52
52
uint32_t skin_stride;
53
53
RS::get_singleton ()->mesh_surface_make_offsets_from_format (surface_data.format , surface_data.vertex_count , surface_data.index_count , surface_offsets, vertex_stride, normal_tangent_stride, attrib_stride, skin_stride);
54
54
55
- buffer = surface_data.vertex_data ;
55
+ buffer_curr = surface_data.vertex_data ;
56
+ vertex_count = surface_data.vertex_count ;
56
57
stride = vertex_stride;
57
58
normal_stride = normal_tangent_stride;
58
59
offset_vertices = surface_offsets[RS::ARRAY_VERTEX];
59
60
offset_normal = surface_offsets[RS::ARRAY_NORMAL];
60
61
}
61
62
62
63
void SoftBodyRenderingServerHandler::clear () {
63
- buffer.resize (0 );
64
+ aabb_prev = AABB ();
65
+ buffer_prev.resize (0 );
66
+ buffer_curr.resize (0 );
67
+ buffer_interp.resize (0 );
64
68
stride = 0 ;
65
69
normal_stride = 0 ;
66
70
offset_vertices = 0 ;
@@ -71,15 +75,70 @@ void SoftBodyRenderingServerHandler::clear() {
71
75
}
72
76
73
77
void SoftBodyRenderingServerHandler::open () {
74
- write_buffer = buffer .ptrw ();
78
+ write_buffer = buffer_curr .ptrw ();
75
79
}
76
80
77
81
void SoftBodyRenderingServerHandler::close () {
78
82
write_buffer = nullptr ;
79
83
}
80
84
81
- void SoftBodyRenderingServerHandler::commit_changes () {
82
- RS::get_singleton ()->mesh_surface_update_vertex_region (mesh, surface, 0 , buffer);
85
+ void SoftBodyRenderingServerHandler::fti_pump () {
86
+ if (buffer_prev.is_empty ()) {
87
+ buffer_prev.resize (buffer_curr.size ());
88
+ }
89
+ SWAP (buffer_prev, buffer_curr);
90
+ aabb_prev = aabb_curr;
91
+ }
92
+
93
+ void SoftBodyRenderingServerHandler::commit_changes (real_t p_interpolation_fraction) {
94
+ real_t f = p_interpolation_fraction;
95
+ AABB aabb_interp = aabb_curr;
96
+
97
+ if (buffer_interp.is_empty ()) {
98
+ buffer_interp.resize (buffer_curr.size ());
99
+ }
100
+
101
+ if (p_interpolation_fraction < 1 ) {
102
+ // AABB.
103
+ if (aabb_prev != AABB () && aabb_curr != AABB ()) {
104
+ aabb_interp = AABB (aabb_prev.position .lerp (aabb_curr.position , f), aabb_prev.size .lerp (aabb_curr.size , f));
105
+ }
106
+
107
+ const float *vertex_prev = reinterpret_cast <const float *>(buffer_prev.ptr () + offset_vertices);
108
+ const float *vertex_curr = reinterpret_cast <const float *>(buffer_curr.ptr () + offset_vertices);
109
+ float *vertex_interp = reinterpret_cast <float *>(buffer_interp.ptrw () + offset_vertices);
110
+
111
+ const uint32_t *normal_prev = reinterpret_cast <const uint32_t *>(buffer_prev.ptr () + offset_normal);
112
+ const uint32_t *normal_curr = reinterpret_cast <const uint32_t *>(buffer_curr.ptr () + offset_normal);
113
+ uint32_t *normal_interp = reinterpret_cast <uint32_t *>(buffer_interp.ptrw () + offset_normal);
114
+
115
+ for (uint32_t i = 0 ; i < vertex_count; i++) {
116
+ // Vertex.
117
+ vertex_interp[0 ] = Math::lerp (vertex_prev[0 ], vertex_curr[0 ], (float )f);
118
+ vertex_interp[1 ] = Math::lerp (vertex_prev[1 ], vertex_curr[1 ], (float )f);
119
+ vertex_interp[2 ] = Math::lerp (vertex_prev[2 ], vertex_curr[2 ], (float )f);
120
+
121
+ vertex_prev += stride / sizeof (float );
122
+ vertex_curr += stride / sizeof (float );
123
+ vertex_interp += stride / sizeof (float );
124
+
125
+ // Normal.
126
+ Vector2 prev = Vector2 ((normal_prev[0 ] & 0xffff ) / 65535 .0f , (normal_prev[0 ] >> 16 ) / 65535 .0f );
127
+ Vector2 curr = Vector2 ((normal_curr[0 ] & 0xffff ) / 65535 .0f , (normal_curr[0 ] >> 16 ) / 65535 .0f );
128
+ Vector2 interp = Vector3::octahedron_decode (prev).lerp (Vector3::octahedron_decode (curr), f).octahedron_encode ();
129
+ uint32_t n = 0 ;
130
+ n |= (uint16_t )CLAMP (interp.x * 65535 , 0 , 65535 );
131
+ n |= (uint16_t )CLAMP (interp.y * 65535 , 0 , 65535 ) << 16 ;
132
+ normal_interp[0 ] = n;
133
+
134
+ normal_prev += normal_stride / sizeof (uint32_t );
135
+ normal_curr += normal_stride / sizeof (uint32_t );
136
+ normal_interp += normal_stride / sizeof (uint32_t );
137
+ }
138
+ }
139
+
140
+ RS::get_singleton ()->mesh_set_custom_aabb (mesh, aabb_interp);
141
+ RS::get_singleton ()->mesh_surface_update_vertex_region (mesh, surface, 0 , p_interpolation_fraction < 1 ? buffer_interp : buffer_curr);
83
142
}
84
143
85
144
void SoftBodyRenderingServerHandler::set_vertex (int p_vertex_id, const Vector3 &p_vertex) {
@@ -98,7 +157,7 @@ void SoftBodyRenderingServerHandler::set_normal(int p_vertex_id, const Vector3 &
98
157
}
99
158
100
159
void SoftBodyRenderingServerHandler::set_aabb (const AABB &p_aabb) {
101
- RS::get_singleton ()-> mesh_set_custom_aabb (mesh, p_aabb) ;
160
+ aabb_curr = p_aabb;
102
161
}
103
162
104
163
SoftBody3D::PinnedPoint::PinnedPoint () {
@@ -274,7 +333,16 @@ void SoftBody3D::_notification(int p_what) {
274
333
PhysicsServer3D::get_singleton ()->soft_body_set_space (physics_rid, space);
275
334
_prepare_physics_server ();
276
335
} break ;
277
-
336
+ case NOTIFICATION_INTERNAL_PROCESS: {
337
+ if (is_inside_tree ()) {
338
+ _commit_soft_mesh (is_physics_interpolated_and_enabled () ? Engine::get_singleton ()->get_physics_interpolation_fraction () : 1 );
339
+ }
340
+ } break ;
341
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
342
+ if (is_inside_tree ()) {
343
+ _update_soft_mesh ();
344
+ }
345
+ } break ;
278
346
case NOTIFICATION_READY: {
279
347
if (!parent_collision_ignore.is_empty ()) {
280
348
add_collision_exception_with (get_node (parent_collision_ignore));
@@ -295,7 +363,11 @@ void SoftBody3D::_notification(int p_what) {
295
363
set_transform (Transform3D ());
296
364
set_notify_transform (true );
297
365
} break ;
298
-
366
+ case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: {
367
+ if (mesh.is_valid () && rendering_server_handler->is_ready (mesh->get_rid ())) {
368
+ rendering_server_handler->fti_pump ();
369
+ }
370
+ } break ;
299
371
case NOTIFICATION_VISIBILITY_CHANGED: {
300
372
_update_pickable ();
301
373
} break ;
@@ -394,6 +466,13 @@ void SoftBody3D::_bind_methods() {
394
466
BIND_ENUM_CONSTANT (DISABLE_MODE_KEEP_ACTIVE);
395
467
}
396
468
469
+ void SoftBody3D::_physics_interpolated_changed () {
470
+ if (mesh.is_valid () && rendering_server_handler->is_ready (mesh->get_rid ())) {
471
+ rendering_server_handler->fti_pump ();
472
+ }
473
+ MeshInstance3D::_physics_interpolated_changed ();
474
+ }
475
+
397
476
PackedStringArray SoftBody3D::get_configuration_warnings () const {
398
477
PackedStringArray warnings = MeshInstance3D::get_configuration_warnings ();
399
478
@@ -420,7 +499,7 @@ void SoftBody3D::_update_physics_server() {
420
499
}
421
500
}
422
501
423
- void SoftBody3D::_draw_soft_mesh () {
502
+ void SoftBody3D::_update_soft_mesh () {
424
503
if (mesh.is_null ()) {
425
504
return ;
426
505
}
@@ -443,11 +522,18 @@ void SoftBody3D::_draw_soft_mesh() {
443
522
444
523
_update_physics_server ();
445
524
525
+ if (is_physics_interpolated_and_enabled ()) {
526
+ rendering_server_handler->fti_pump ();
527
+ }
446
528
rendering_server_handler->open ();
447
529
PhysicsServer3D::get_singleton ()->soft_body_update_rendering_server (physics_rid, rendering_server_handler);
448
530
rendering_server_handler->close ();
531
+ }
449
532
450
- rendering_server_handler->commit_changes ();
533
+ void SoftBody3D::_commit_soft_mesh (real_t p_interpolation_fraction) {
534
+ if (mesh.is_valid () && rendering_server_handler->is_ready (mesh->get_rid ())) {
535
+ rendering_server_handler->commit_changes (p_interpolation_fraction);
536
+ }
451
537
}
452
538
453
539
void SoftBody3D::_prepare_physics_server () {
@@ -470,12 +556,12 @@ void SoftBody3D::_prepare_physics_server() {
470
556
mesh_rid = mesh->get_rid ();
471
557
}
472
558
PhysicsServer3D::get_singleton ()->soft_body_set_mesh (physics_rid, mesh_rid);
473
- RS::get_singleton ()->connect (" frame_pre_draw" , callable_mp (this , &SoftBody3D::_draw_soft_mesh));
559
+ set_process_internal (true );
560
+ set_physics_process_internal (true );
474
561
} else {
475
562
PhysicsServer3D::get_singleton ()->soft_body_set_mesh (physics_rid, RID ());
476
- if (RS::get_singleton ()->is_connected (" frame_pre_draw" , callable_mp (this , &SoftBody3D::_draw_soft_mesh))) {
477
- RS::get_singleton ()->disconnect (" frame_pre_draw" , callable_mp (this , &SoftBody3D::_draw_soft_mesh));
478
- }
563
+ set_process_internal (false );
564
+ set_physics_process_internal (false );
479
565
}
480
566
}
481
567
0 commit comments