From c8d6aac54d6afd21229433c702513690aa5f9f0a Mon Sep 17 00:00:00 2001 From: Bosheng Li Date: Wed, 16 Oct 2024 16:45:45 -0400 Subject: [PATCH] First working version. --- .../StiffRodStretchShearConstraints.comp | 19 +++++-- .../Shaders/Includes/DynamicStrands.glsl | 4 ++ .../include/StrandModel/BrokenBranch.hpp | 2 +- .../include/StrandModel/DynamicStrands.hpp | 12 ++++- .../EcoSysLab/src/BrokenBranch.cpp | 51 +++++++++++-------- .../EcoSysLab/src/DynamicStrands.cpp | 3 ++ .../EcoSysLab/src/DynamicStrandsPhysics.cpp | 12 ++--- 7 files changed, 68 insertions(+), 35 deletions(-) diff --git a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrands/Constraints/StiffRodStretchShearConstraints.comp b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrands/Constraints/StiffRodStretchShearConstraints.comp index 0e69221..992fb7f 100644 --- a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrands/Constraints/StiffRodStretchShearConstraints.comp +++ b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Compute/DynamicStrands/Constraints/StiffRodStretchShearConstraints.comp @@ -61,6 +61,9 @@ void project_constraint(in int segment_handle){ vec3 p0 = particle0.x.xyz; vec3 p1 = particle1.x.xyz; + + + float inv_mass_p0 = particle0.acceleration_inv_mass.w; float inv_mass_p1 = particle1.acceleration_inv_mass.w; vec4 q = segment.q; @@ -68,10 +71,18 @@ void project_constraint(in int segment_handle){ vec3 stretching_and_shearing_k = vec3(segment.shearing_stiffness, segment.shearing_stiffness, segment.stretching_stiffness); float rest_length = segment.torque_rest_length.w; + + segments[segment_handle].p0.xyz = p0; + segments[segment_handle].p1.xyz = p1; + segments[segment_handle].p0.w = intBitsToFloat(particle0_handle); + segments[segment_handle].p1.w = intBitsToFloat(particle1_handle); + + segments[segment_handle].original_gamma.xyz = (p1 - p0) / rest_length; + vec3 d3; - d3[0] = 2.0 * (q.x * q.z + q.w * q.y); - d3[1] = 2.0 * (q.y * q.z - q.w * q.x); - d3[2] = q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z; + d3[0] = -2.0 * (q.x * q.z + q.w * q.y); + d3[1] = -2.0 * (q.y * q.z - q.w * q.x); + d3[2] = -q.w * q.w + q.x * q.x + q.y * q.y - q.z * q.z; vec3 gamma = (p1 - p0) / rest_length - d3; gamma /= (inv_mass_p0 + inv_mass_p1) / rest_length + inv_mass_q * 4.0 * rest_length + 1e-6; @@ -101,5 +112,7 @@ void project_constraint(in int segment_handle){ particles[particle1_handle].x.xyz += x1_correction; segments[segment_handle].q = normalize(q_correction + segment.q); + + segments[segment_handle].d3.xyz = d3; segments[segment_handle].gamma.xyz = gamma; } \ No newline at end of file diff --git a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl index 6267f94..36bb992 100644 --- a/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl +++ b/EvoEngine_Plugins/EcoSysLab/Internals/EcoSysLabResources/Shaders/Includes/DynamicStrands.glsl @@ -36,6 +36,10 @@ struct Segment { int neighbors[8]; + vec4 p0; + vec4 p1; + vec4 original_gamma; + vec4 d3; vec4 gamma; }; diff --git a/EvoEngine_Plugins/EcoSysLab/include/StrandModel/BrokenBranch.hpp b/EvoEngine_Plugins/EcoSysLab/include/StrandModel/BrokenBranch.hpp index fe17e5d..c88c8d8 100644 --- a/EvoEngine_Plugins/EcoSysLab/include/StrandModel/BrokenBranch.hpp +++ b/EvoEngine_Plugins/EcoSysLab/include/StrandModel/BrokenBranch.hpp @@ -35,7 +35,7 @@ class BrokenBranch : public IPrivateComponent { void Subdivide(float segment_length, const StrandModelStrandGroup& src); void InitializeStrandParticles(const StrandModelStrandGroup& strand_group) const; void ClearStrandParticles() const; - + void Step(); void InitializeStrandConcaveMesh(const StrandModelStrandGroup& strand_group, float max_edge_length) const; void ClearStrandConcaveMesh() const; }; diff --git a/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp b/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp index 804f1a1..3d63e4c 100644 --- a/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp +++ b/EvoEngine_Plugins/EcoSysLab/include/StrandModel/DynamicStrands.hpp @@ -27,7 +27,7 @@ class DynamicStrands { struct PhysicsParameters { float time_step = 0.01f; uint32_t sub_step = 1; - uint32_t max_iteration; + uint32_t max_iteration = 20; }; struct RenderParameters { @@ -93,6 +93,13 @@ class DynamicStrands { int neighbors[8]; + glm::vec3 p0; + int p0_handle; + glm::vec3 p1; + int p1_handle; + + glm::vec4 original_gamma; + glm::vec4 d3; glm::vec4 gamma; }; struct GpuParticle { @@ -163,6 +170,7 @@ void DynamicStrands::InitializeStrandsGroup(const InitializeParameters& initiali } }); + segments.resize(target_strand_segments.size()); Jobs::RunParallelFor(target_strand_segments.size(), [&](const size_t i) { auto& segment = segments[i]; @@ -202,7 +210,7 @@ void DynamicStrands::InitializeStrandsGroup(const InitializeParameters& initiali segment.twisting_stiffness = shear_modulus * polar_moment_of_inertia / segment.rest_length;*/ - segment.stretching_stiffness = segment.shearing_stiffness = 1.0f; + segment.stretching_stiffness = segment.shearing_stiffness = 0.5f; segment.bending_stiffness = segment.twisting_stiffness = .5f; }); diff --git a/EvoEngine_Plugins/EcoSysLab/src/BrokenBranch.cpp b/EvoEngine_Plugins/EcoSysLab/src/BrokenBranch.cpp index 1feccf7..3330ded 100644 --- a/EvoEngine_Plugins/EcoSysLab/src/BrokenBranch.cpp +++ b/EvoEngine_Plugins/EcoSysLab/src/BrokenBranch.cpp @@ -135,7 +135,7 @@ bool BrokenBranch::OnInspect(const std::shared_ptr& editor_layer) { step_parameters.physics = true; const bool resume_render = step_parameters.render; step_parameters.render = false; - dynamic_strands.Step(step_parameters); + Step(); step_parameters.physics = false; step_parameters.render = resume_render; } @@ -145,6 +145,8 @@ bool BrokenBranch::OnInspect(const std::shared_ptr& editor_layer) { dynamic_strands.Download(); EVOENGINE_LOG("Downloaded data from GPU") } + + ImGui::SameLine(); if (ImGui::Button("Upload strands")) { dynamic_strands.Upload(); @@ -155,24 +157,7 @@ bool BrokenBranch::OnInspect(const std::shared_ptr& editor_layer) { return false; } void BrokenBranch::LateUpdate() { - if (enable_simulation && !dynamic_strands.segments.empty()) { - const auto owner = GetOwner(); - const auto scene = GetScene(); - const auto current_root_transform = scene->GetDataComponent(owner); - GlobalTransform original_inverse_root_transform; - original_inverse_root_transform.value = glm::inverse(initialize_parameters.root_transform.value); - Jobs::RunParallelFor(position_update->commands.size(), [&](const size_t i) { - auto& command = position_update->commands[i]; - command.new_position = current_root_transform.TransformPoint( - original_inverse_root_transform.TransformPoint(dynamic_strands.particles[command.particle_index].x0)); - }); - dynamic_strands.operators.clear(); - //dynamic_strands.operators.emplace_back(external_force); - dynamic_strands.operators.emplace_back(position_update); - const auto editor_layer = Application::GetLayer(); - step_parameters.render_parameters.target_camera = editor_layer->GetSceneCamera(); - dynamic_strands.Step(step_parameters); - } + Step(); } void BrokenBranch::FixedUpdate() { @@ -201,11 +186,13 @@ void BrokenBranch::ExperimentSetup() { const auto strand1_handle = strand_group.AllocateStrand(); auto& segment1 = strand_group.RefStrandSegment(strand_group.Extend(strand1_handle)); auto& strand1 = strand_group.RefStrand(strand1_handle); - segment1.end_position = glm::vec3(0, 0.5f, 0.); + segment1.end_position = glm::vec3(0, 5.0f, 0.); strand1.start_color = segment1.end_color = glm::vec4(1, 0, 0, 0); - strand1.start_thickness = segment1.end_thickness = 0.01f; + strand1.start_thickness = segment1.end_thickness = 0.1f; strand_group.CalculateRotations(); + + Subdivide(2, strand_group); } void BrokenBranch::Subdivide(const float segment_length, const StrandModelStrandGroup& src) { @@ -251,6 +238,28 @@ void BrokenBranch::ClearStrandParticles() const { } } +void BrokenBranch::Step() { + if (!dynamic_strands.segments.empty()) { + dynamic_strands.operators.clear(); + if (step_parameters.physics) { + const auto owner = GetOwner(); + const auto scene = GetScene(); + const auto current_root_transform = scene->GetDataComponent(owner); + GlobalTransform original_inverse_root_transform; + original_inverse_root_transform.value = glm::inverse(initialize_parameters.root_transform.value); + Jobs::RunParallelFor(position_update->commands.size(), [&](const size_t i) { + auto& command = position_update->commands[i]; + command.new_position = current_root_transform.TransformPoint( + original_inverse_root_transform.TransformPoint(dynamic_strands.particles[command.particle_index].x0)); + }); + dynamic_strands.operators.emplace_back(position_update); + } + const auto editor_layer = Application::GetLayer(); + step_parameters.render_parameters.target_camera = editor_layer->GetSceneCamera(); + dynamic_strands.Step(step_parameters); + } +} + void BrokenBranch::InitializeStrandConcaveMesh(const StrandModelStrandGroup& strand_group, const float max_edge_length) const { const auto scene = GetScene(); diff --git a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp index 4d87063..592ba2b 100644 --- a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp +++ b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrands.cpp @@ -57,6 +57,8 @@ void DynamicStrands::Step(const StepParameters& target_step_parameters) { void DynamicStrands::Upload() const { device_strands_buffer->UploadVector(strands); device_segments_buffer->UploadVector(segments); + device_particles_buffer->UploadVector(particles); + for (const auto& op : operators) { op->UploadData(); } @@ -68,6 +70,7 @@ void DynamicStrands::Upload() const { void DynamicStrands::Download() { device_strands_buffer->DownloadVector(strands, strands.size()); device_segments_buffer->DownloadVector(segments, segments.size()); + device_particles_buffer->DownloadVector(particles, particles.size()); for (const auto& op : operators) { op->DownloadData(); } diff --git a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsPhysics.cpp b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsPhysics.cpp index 4f65a27..0b2dabb 100644 --- a/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsPhysics.cpp +++ b/EvoEngine_Plugins/EcoSysLab/src/DynamicStrandsPhysics.cpp @@ -394,12 +394,9 @@ void DsStiffRod::Project(const DynamicStrands::PhysicsParameters& physics_parame strands_physics_descriptor_sets[current_frame_index]->UpdateBufferDescriptorBinding(0, per_strand_data_list_buffer); strands_physics_descriptor_sets[current_frame_index]->UpdateBufferDescriptorBinding(1, rod_constraints_buffer); - int num_sub_step = 1; - int num_iteration = 1; - InitConstraintConstant init_push_constant; init_push_constant.constraint_size = rod_constraints.size(); - init_push_constant.time_step = physics_parameters.time_step / num_sub_step; + init_push_constant.time_step = physics_parameters.time_step / physics_parameters.sub_step; StretchShearConstraintConstant stretch_shear_constraint_constant; stretch_shear_constraint_constant.strand_size = per_strand_data_list.size(); @@ -412,7 +409,7 @@ void DsStiffRod::Project(const DynamicStrands::PhysicsParameters& physics_parame Platform::RecordCommandsMainQueue([&](const VkCommandBuffer vk_command_buffer) { Platform::EverythingBarrier(vk_command_buffer); - for (int sub_step_i = 0; sub_step_i < num_sub_step; sub_step_i++) { + for (int sub_step_i = 0; sub_step_i < physics_parameters.sub_step; sub_step_i++) { init_constraint_pipeline->Bind(vk_command_buffer); init_constraint_pipeline->BindDescriptorSet( vk_command_buffer, 0, @@ -423,8 +420,7 @@ void DsStiffRod::Project(const DynamicStrands::PhysicsParameters& physics_parame init_constraint_pipeline->PushConstant(vk_command_buffer, 0, init_push_constant); vkCmdDispatch(vk_command_buffer, Platform::DivUp(init_push_constant.constraint_size, task_work_group_invocations), 1, 1); - Platform::EverythingBarrier(vk_command_buffer); - for (int iteration_i = 0; iteration_i < num_iteration; iteration_i++) { + for (int iteration_i = 0; iteration_i < physics_parameters.max_iteration; iteration_i++) { stretch_shear_constraint_pipeline->Bind(vk_command_buffer); stretch_shear_constraint_pipeline->BindDescriptorSet( vk_command_buffer, 0, @@ -437,7 +433,7 @@ void DsStiffRod::Project(const DynamicStrands::PhysicsParameters& physics_parame Platform::DivUp(stretch_shear_constraint_constant.strand_size, task_work_group_invocations), 1, 1); Platform::EverythingBarrier(vk_command_buffer); - + bend_twist_constraint_pipeline->Bind(vk_command_buffer); bend_twist_constraint_pipeline->BindDescriptorSet( vk_command_buffer, 0,