|
|
@ -15,6 +15,32 @@ |
|
|
|
#include "timer.hpp" |
|
|
|
#include "timer.hpp" |
|
|
|
#include "grabber.hpp" |
|
|
|
#include "grabber.hpp" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct SizesUniformData { |
|
|
|
|
|
|
|
uint32_t vertexCount; |
|
|
|
|
|
|
|
uint32_t faceCount; |
|
|
|
|
|
|
|
uint32_t edgeCount; |
|
|
|
|
|
|
|
uint32_t triangleCount; |
|
|
|
|
|
|
|
uint32_t tetrahedronCount; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct CameraUniformData { |
|
|
|
|
|
|
|
glm::mat4 view; |
|
|
|
|
|
|
|
glm::mat4 projection; |
|
|
|
|
|
|
|
glm::vec2 viewport; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct GrabPushData { |
|
|
|
|
|
|
|
uint32_t state; |
|
|
|
|
|
|
|
alignas(8) glm::vec2 screenPosition; |
|
|
|
|
|
|
|
glm::vec2 screenDelta; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct PBDPushData { |
|
|
|
|
|
|
|
uint32_t state; |
|
|
|
|
|
|
|
ConstraintData::Partition edgePartition; |
|
|
|
|
|
|
|
ConstraintData::Partition tetrahedronPartition; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Application::Application() { |
|
|
|
Application::Application() { |
|
|
|
createSyncObjects(); |
|
|
|
createSyncObjects(); |
|
|
|
swapchain = make_unique<Swapchain>(); |
|
|
|
swapchain = make_unique<Swapchain>(); |
|
|
@ -46,22 +72,22 @@ Application::Application() { |
|
|
|
|
|
|
|
|
|
|
|
createMeshBuffers(); |
|
|
|
createMeshBuffers(); |
|
|
|
|
|
|
|
|
|
|
|
SizeInformation sizeInformation {}; |
|
|
|
SizesUniformData sizeInformation {}; |
|
|
|
sizeInformation.vertexCount = vertexBuffers[0]->size / sizeof(Vertex); |
|
|
|
sizeInformation.vertexCount = vertexBuffers[0]->size / sizeof(Vertex); |
|
|
|
sizeInformation.faceCount = faceBuffer->size / sizeof(Face); |
|
|
|
sizeInformation.faceCount = faceBuffer->size / sizeof(Face); |
|
|
|
|
|
|
|
|
|
|
|
sizeInformationBuffer = make_unique<Buffer>( |
|
|
|
sizeInformationBuffer = make_unique<Buffer>( |
|
|
|
sizeof(SizeInformation), &sizeInformation, sizeof(sizeInformation), |
|
|
|
sizeof(SizesUniformData), &sizeInformation, sizeof(sizeInformation), |
|
|
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, |
|
|
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, |
|
|
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); |
|
|
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); |
|
|
|
sizeInformationBuffer->setName("Sizes"); |
|
|
|
sizeInformationBuffer->setName("Sizes"); |
|
|
|
|
|
|
|
|
|
|
|
simulationProperties.gravity = {0, -9.81, 0}; |
|
|
|
simulationUniformData.gravity = {0, -9.81, 0}; |
|
|
|
simulationProperties.k = 10; |
|
|
|
simulationUniformData.k = 10; |
|
|
|
simulationProperties.dt = 1.f / 60.f; |
|
|
|
simulationUniformData.dt = 1.f / 60.f; |
|
|
|
|
|
|
|
|
|
|
|
propertiesBuffer = make_unique<Buffer>( |
|
|
|
propertiesBuffer = make_unique<Buffer>( |
|
|
|
sizeof(SimulationProperties), &simulationProperties, sizeof(simulationProperties), |
|
|
|
sizeof(SimulationUniformData), &simulationUniformData, sizeof(simulationUniformData), |
|
|
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, |
|
|
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, |
|
|
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); |
|
|
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); |
|
|
|
propertiesBuffer->setName("Simulation properties"); |
|
|
|
propertiesBuffer->setName("Simulation properties"); |
|
|
@ -97,9 +123,9 @@ void Application::mainLoop() { |
|
|
|
update(); |
|
|
|
update(); |
|
|
|
auto t2 = system_clock::now(); |
|
|
|
auto t2 = system_clock::now(); |
|
|
|
|
|
|
|
|
|
|
|
auto updateDuration = duration<float>(t2 - t1); |
|
|
|
auto measuredUpdateDuration = duration<float>(t2 - t1); |
|
|
|
auto sleepDuration = duration<float>(simulationProperties.dt); |
|
|
|
auto requestedUpdateDuration = duration<float>(simulationUniformData.dt); |
|
|
|
std::this_thread::sleep_for(sleepDuration - updateDuration); |
|
|
|
std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
@ -265,7 +291,7 @@ void Application::createComputePipelines() { |
|
|
|
pushRanges.push_back({ |
|
|
|
pushRanges.push_back({ |
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, |
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, |
|
|
|
.offset = 0, |
|
|
|
.offset = 0, |
|
|
|
.size = sizeof(GrabPushConstants) |
|
|
|
.size = sizeof(GrabPushData) |
|
|
|
}); |
|
|
|
}); |
|
|
|
grabPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/grab.spv", layouts, pushRanges)); |
|
|
|
grabPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/grab.spv", layouts, pushRanges)); |
|
|
|
} |
|
|
|
} |
|
|
@ -299,7 +325,6 @@ void Application::createComputePipelines() { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Application::updateCameraBuffer() { |
|
|
|
void Application::updateCameraBuffer() { |
|
|
|
CameraUniformData ubo {}; |
|
|
|
CameraUniformData ubo {}; |
|
|
|
ubo.view = camera->view(); |
|
|
|
ubo.view = camera->view(); |
|
|
@ -308,11 +333,6 @@ void Application::updateCameraBuffer() { |
|
|
|
ubo.viewport = camera->viewport(); |
|
|
|
ubo.viewport = camera->viewport(); |
|
|
|
|
|
|
|
|
|
|
|
memcpy(cameraUniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(CameraUniformData)); |
|
|
|
memcpy(cameraUniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(CameraUniformData)); |
|
|
|
|
|
|
|
|
|
|
|
vmaFlushAllocation(Instance::GetAllocator(), |
|
|
|
|
|
|
|
cameraUniformBuffer->allocation, |
|
|
|
|
|
|
|
cameraUniformBuffer->allocationInfo.offset, |
|
|
|
|
|
|
|
cameraUniformBuffer->allocationInfo.size); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Application::drawFrame(float dt) { |
|
|
|
void Application::drawFrame(float dt) { |
|
|
@ -544,12 +564,12 @@ void Application::recordGrabCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 1, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); |
|
|
|
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 1, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr); |
|
|
|
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 2, 1, &descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr); |
|
|
|
vkCmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 2, 1, &descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr); |
|
|
|
|
|
|
|
|
|
|
|
GrabPushConstants pushConstants {}; |
|
|
|
GrabPushData pushConstants {}; |
|
|
|
|
|
|
|
|
|
|
|
if (grabber->started()){ |
|
|
|
if (grabber->started()){ |
|
|
|
pushConstants.state = 0; |
|
|
|
pushConstants.state = 0; |
|
|
|
pushConstants.screenPosition = grabber->previousCursorPosition; |
|
|
|
pushConstants.screenPosition = grabber->previousCursorPosition; |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushConstants), &pushConstants); |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); |
|
|
|
|
|
|
|
|
|
|
|
uint32_t faceInvocations = GetGroupCount(faceBuffer->size / sizeof(Face), BLOCK_SIZE_GRAB); |
|
|
|
uint32_t faceInvocations = GetGroupCount(faceBuffer->size / sizeof(Face), BLOCK_SIZE_GRAB); |
|
|
|
|
|
|
|
|
|
|
@ -559,7 +579,7 @@ void Application::recordGrabCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
0, nullptr, 0, nullptr); |
|
|
|
0, nullptr, 0, nullptr); |
|
|
|
|
|
|
|
|
|
|
|
pushConstants.state = 1; |
|
|
|
pushConstants.state = 1; |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushConstants), &pushConstants); |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); |
|
|
|
vkCmdDispatch(cmdBuffer, 1, 1, 1); |
|
|
|
vkCmdDispatch(cmdBuffer, 1, 1, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -570,7 +590,7 @@ void Application::recordGrabCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
if (grabber->moved(screenDelta)){ |
|
|
|
if (grabber->moved(screenDelta)){ |
|
|
|
pushConstants.state = 2; |
|
|
|
pushConstants.state = 2; |
|
|
|
pushConstants.screenDelta = screenDelta; |
|
|
|
pushConstants.screenDelta = screenDelta; |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushConstants), &pushConstants); |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); |
|
|
|
vkCmdDispatch(cmdBuffer, 1, 1, 1); |
|
|
|
vkCmdDispatch(cmdBuffer, 1, 1, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -579,7 +599,7 @@ void Application::recordGrabCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
|
|
|
|
|
|
|
|
if (grabber->stopped()){ |
|
|
|
if (grabber->stopped()){ |
|
|
|
pushConstants.state = 3; |
|
|
|
pushConstants.state = 3; |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushConstants), &pushConstants); |
|
|
|
vkCmdPushConstants(cmdBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants); |
|
|
|
vkCmdDispatch(cmdBuffer, 1, 1, 1); |
|
|
|
vkCmdDispatch(cmdBuffer, 1, 1, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -601,7 +621,7 @@ void Application::recordPBDCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
|
|
|
|
|
|
|
|
uint32_t state; |
|
|
|
uint32_t state; |
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < simulationProperties.k; i++){ |
|
|
|
for (size_t i = 0; i < simulationUniformData.k; i++){ |
|
|
|
state = 0; |
|
|
|
state = 0; |
|
|
|
vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); |
|
|
|
vkCmdPushConstants(cmdBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state); |
|
|
|
vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); |
|
|
|
vkCmdDispatch(cmdBuffer, vertexGroupCount, 1, 1); |
|
|
|