@@ -52,15 +52,24 @@ 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[0 ] = 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];
61
+
62
+ buffer_curr = &buffer[0 ];
63
+ buffer_prev = &buffer[1 ];
60
64
}
61
65
62
66
void SoftBodyRenderingServerHandler::clear () {
63
- buffer.resize (0 );
67
+ aabb_prev = AABB ();
68
+ buffer[0 ].resize (0 );
69
+ buffer[1 ].resize (0 );
70
+ buffer_curr = nullptr ;
71
+ buffer_prev = nullptr ;
72
+ buffer_interp.resize (0 );
64
73
stride = 0 ;
65
74
normal_stride = 0 ;
66
75
offset_vertices = 0 ;
@@ -71,15 +80,73 @@ void SoftBodyRenderingServerHandler::clear() {
71
80
}
72
81
73
82
void SoftBodyRenderingServerHandler::open () {
74
- write_buffer = buffer. ptrw ();
83
+ write_buffer = buffer_curr-> ptrw ();
75
84
}
76
85
77
86
void SoftBodyRenderingServerHandler::close () {
78
87
write_buffer = nullptr ;
79
88
}
80
89
81
- void SoftBodyRenderingServerHandler::commit_changes () {
82
- RS::get_singleton ()->mesh_surface_update_vertex_region (mesh, surface, 0 , buffer);
90
+ void SoftBodyRenderingServerHandler::fti_pump () {
91
+ if (buffer_prev->is_empty ()) {
92
+ buffer_prev->resize (buffer_curr->size ());
93
+ }
94
+ SWAP (buffer_prev, buffer_curr);
95
+ aabb_prev = aabb_curr;
96
+ }
97
+
98
+ void SoftBodyRenderingServerHandler::commit_changes (real_t p_interpolation_fraction) {
99
+ real_t f = p_interpolation_fraction;
100
+ AABB aabb_interp = aabb_curr;
101
+
102
+ if (p_interpolation_fraction < 1 ) {
103
+ if (buffer_interp.is_empty ()) {
104
+ buffer_interp.resize (buffer_curr->size ());
105
+ }
106
+
107
+ // AABB.
108
+ if (aabb_prev != AABB () && aabb_curr != AABB ()) {
109
+ aabb_interp = AABB (aabb_prev.position .lerp (aabb_curr.position , f), aabb_prev.size .lerp (aabb_curr.size , f));
110
+ }
111
+
112
+ const float *vertex_prev = reinterpret_cast <const float *>(buffer_prev->ptr () + offset_vertices);
113
+ const float *vertex_curr = reinterpret_cast <const float *>(buffer_curr->ptr () + offset_vertices);
114
+ float *vertex_interp = reinterpret_cast <float *>(buffer_interp.ptrw () + offset_vertices);
115
+
116
+ const uint32_t *normal_prev = reinterpret_cast <const uint32_t *>(buffer_prev->ptr () + offset_normal);
117
+ const uint32_t *normal_curr = reinterpret_cast <const uint32_t *>(buffer_curr->ptr () + offset_normal);
118
+ uint32_t *normal_interp = reinterpret_cast <uint32_t *>(buffer_interp.ptrw () + offset_normal);
119
+
120
+ uint32_t stride_units = stride / sizeof (float );
121
+ uint32_t normal_stride_units = normal_stride / sizeof (uint32_t );
122
+
123
+ for (uint32_t i = 0 ; i < vertex_count; i++) {
124
+ // Vertex.
125
+ vertex_interp[0 ] = Math::lerp (vertex_prev[0 ], vertex_curr[0 ], (float )f);
126
+ vertex_interp[1 ] = Math::lerp (vertex_prev[1 ], vertex_curr[1 ], (float )f);
127
+ vertex_interp[2 ] = Math::lerp (vertex_prev[2 ], vertex_curr[2 ], (float )f);
128
+
129
+ vertex_prev += stride_units;
130
+ vertex_curr += stride_units;
131
+ vertex_interp += stride_units;
132
+
133
+ // Normal.
134
+ Vector2 prev = Vector2 ((normal_prev[0 ] & 0xffff ) / 65535 .0f , (normal_prev[0 ] >> 16 ) / 65535 .0f );
135
+ Vector2 curr = Vector2 ((normal_curr[0 ] & 0xffff ) / 65535 .0f , (normal_curr[0 ] >> 16 ) / 65535 .0f );
136
+ Vector2 interp = Vector3::octahedron_decode (prev).lerp (Vector3::octahedron_decode (curr), f).octahedron_encode ();
137
+ uint32_t n = 0 ;
138
+ n |= (uint16_t )CLAMP (interp.x * 65535 , 0 , 65535 );
139
+ n |= (uint16_t )CLAMP (interp.y * 65535 , 0 , 65535 ) << 16 ;
140
+ normal_interp[0 ] = n;
141
+
142
+ normal_prev += normal_stride_units;
143
+ normal_curr += normal_stride_units;
144
+ normal_interp += normal_stride_units;
145
+ }
146
+ }
147
+
148
+ RS::get_singleton ()->mesh_set_custom_aabb (mesh, aabb_interp);
149
+ RS::get_singleton ()->mesh_surface_update_vertex_region (mesh, surface, 0 , p_interpolation_fraction < 1 ? buffer_interp : *buffer_curr);
83
150
}
84
151
85
152
void SoftBodyRenderingServerHandler::set_vertex (int p_vertex_id, const Vector3 &p_vertex) {
@@ -98,7 +165,7 @@ void SoftBodyRenderingServerHandler::set_normal(int p_vertex_id, const Vector3 &
98
165
}
99
166
100
167
void SoftBodyRenderingServerHandler::set_aabb (const AABB &p_aabb) {
101
- RS::get_singleton ()-> mesh_set_custom_aabb (mesh, p_aabb) ;
168
+ aabb_curr = p_aabb;
102
169
}
103
170
104
171
SoftBody3D::PinnedPoint::PinnedPoint () {
@@ -274,7 +341,19 @@ void SoftBody3D::_notification(int p_what) {
274
341
PhysicsServer3D::get_singleton ()->soft_body_set_space (physics_rid, space);
275
342
_prepare_physics_server ();
276
343
} break ;
277
-
344
+ case NOTIFICATION_INTERNAL_PROCESS: {
345
+ if (is_inside_tree () && is_physics_interpolated_and_enabled ()) {
346
+ _commit_soft_mesh (Engine::get_singleton ()->get_physics_interpolation_fraction ());
347
+ }
348
+ } break ;
349
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
350
+ if (is_inside_tree ()) {
351
+ _update_soft_mesh ();
352
+ if (!is_physics_interpolated_and_enabled ()) {
353
+ _commit_soft_mesh (1 );
354
+ }
355
+ }
356
+ } break ;
278
357
case NOTIFICATION_READY: {
279
358
if (!parent_collision_ignore.is_empty ()) {
280
359
add_collision_exception_with (get_node (parent_collision_ignore));
@@ -295,7 +374,11 @@ void SoftBody3D::_notification(int p_what) {
295
374
set_transform (Transform3D ());
296
375
set_notify_transform (true );
297
376
} break ;
298
-
377
+ case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: {
378
+ if (mesh.is_valid () && rendering_server_handler->is_ready (mesh->get_rid ())) {
379
+ rendering_server_handler->fti_pump ();
380
+ }
381
+ } break ;
299
382
case NOTIFICATION_VISIBILITY_CHANGED: {
300
383
_update_pickable ();
301
384
} break ;
@@ -394,6 +477,13 @@ void SoftBody3D::_bind_methods() {
394
477
BIND_ENUM_CONSTANT (DISABLE_MODE_KEEP_ACTIVE);
395
478
}
396
479
480
+ void SoftBody3D::_physics_interpolated_changed () {
481
+ if (mesh.is_valid () && rendering_server_handler->is_ready (mesh->get_rid ())) {
482
+ rendering_server_handler->fti_pump ();
483
+ }
484
+ MeshInstance3D::_physics_interpolated_changed ();
485
+ }
486
+
397
487
PackedStringArray SoftBody3D::get_configuration_warnings () const {
398
488
PackedStringArray warnings = MeshInstance3D::get_configuration_warnings ();
399
489
@@ -420,7 +510,7 @@ void SoftBody3D::_update_physics_server() {
420
510
}
421
511
}
422
512
423
- void SoftBody3D::_draw_soft_mesh () {
513
+ void SoftBody3D::_update_soft_mesh () {
424
514
if (mesh.is_null ()) {
425
515
return ;
426
516
}
@@ -443,11 +533,18 @@ void SoftBody3D::_draw_soft_mesh() {
443
533
444
534
_update_physics_server ();
445
535
536
+ if (is_physics_interpolated_and_enabled ()) {
537
+ rendering_server_handler->fti_pump ();
538
+ }
446
539
rendering_server_handler->open ();
447
540
PhysicsServer3D::get_singleton ()->soft_body_update_rendering_server (physics_rid, rendering_server_handler);
448
541
rendering_server_handler->close ();
542
+ }
449
543
450
- rendering_server_handler->commit_changes ();
544
+ void SoftBody3D::_commit_soft_mesh (real_t p_interpolation_fraction) {
545
+ if (mesh.is_valid () && rendering_server_handler->is_ready (mesh->get_rid ())) {
546
+ rendering_server_handler->commit_changes (p_interpolation_fraction);
547
+ }
451
548
}
452
549
453
550
void SoftBody3D::_prepare_physics_server () {
@@ -470,12 +567,12 @@ void SoftBody3D::_prepare_physics_server() {
470
567
mesh_rid = mesh->get_rid ();
471
568
}
472
569
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));
570
+ set_process_internal (is_physics_interpolated_and_enabled ());
571
+ set_physics_process_internal (true );
474
572
} else {
475
573
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
- }
574
+ set_process_internal (false );
575
+ set_physics_process_internal (false );
479
576
}
480
577
}
481
578
0 commit comments