Skip to content

Commit

Permalink
feat: add move_pos and update cuda demo
Browse files Browse the repository at this point in the history
  • Loading branch information
For-Chance committed Sep 28, 2024
1 parent 0248ead commit 575b54b
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 55 deletions.
59 changes: 30 additions & 29 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,40 +122,41 @@ jobs:
files: build/coverage/coverage.info
verbose: true


check_nvidia_gpu:
runs-on: ubuntu-latest # use own runner with NVIDIA GPU
outputs:
has_gpu: ${{ steps.check_gpu.outputs.has_gpu }}
steps:
- name: Check for NVIDIA GPU
id: check_gpu
run: |
if lspci | grep -i nvidia; then
echo "NVIDIA GPU found."
echo "::set-output name=has_gpu::true"
else
echo "No NVIDIA GPU found."
echo "::set-output name=has_gpu::false"
fi
build_ubuntu_with_cuda:
runs-on: ubuntu-latest
runs-on: ubuntu-latest # use own runner with NVIDIA GPU
needs: check_nvidia_gpu
if: needs.check_nvidia_gpu.outputs.has_gpu == 'true'
steps:
- uses: actions/checkout@v3

- uses: Jimver/[email protected]
- name: Set up CUDA
uses: Jimver/[email protected] # https://github.com/marketplace/actions/cuda-toolkit
with:
# Cuda version
cuda: 11.7.0 # optional, default is 12.5.0
# Only installs specified subpackages, must be in the form of a JSON array. For example, if you only want to install nvcc and visual studio integration: ["nvcc", "visual_studio_integration"] double quotes required! Note that if you want to use this on Linux, 'network' method MUST be used.
sub-packages: '[]' # optional, default is []
# Only installs specified subpackages that do not have the cuda prefix, must be in the form of a JSON array. For example, if you only want to install libcublas and libcufft: ["libcublas", "libcufft"] double quotes required! Note that this only works with 'network' method on only on Linux.
non-cuda-sub-packages: '[]' # optional, default is []
# Installation method, can be either 'local' or 'network'. 'local' downloads the entire installer with all packages and runs that (you can still only install certain packages with sub-packages on Windows). 'network' downloads a smaller executable which only downloads necessary packages which you can define in subPackages
method: network # optional, default is local
# (Linux and 'local' method only) override arguments for the linux .run installer. For example if you don't want samples use ["--toolkit"] double quotes required!
linux-local-args: '["--toolkit", "--samples"]' # optional, default is ["--toolkit", "--samples"]
# Use GitHub cache to cache downloaded installer on GitHub servers
use-github-cache: true # optional, default is true
# Use local cache to cache downloaded installer on the local runner
use-local-cache: true # optional, default is true
# Suffix of log file name in artifact
log-file-suffix: log.txt # optional, default is log.txt

- name: Check for CUDA
id: check_cuda
run: |
if command -v nvcc &> /dev/null; then
echo "CUDA is installed."
echo "has_cuda=true" >> $GITHUB_ENV
else
echo "CUDA is not installed."
echo "has_cuda=false" >> $GITHUB_ENV
fi
cuda: 11.7.0
sub-packages: '[]'
non-cuda-sub-packages: '[]'
method: network
linux-local-args: '["--toolkit", "--samples"]'
use-github-cache: true
use-local-cache: true
log-file-suffix: log.txt

- name: Install dependencies
run: |
Expand Down
Binary file added demo/img/MassSpring3D_cuda_1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 17 additions & 8 deletions test/system_test/MassSpring3D/ClothSimulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@ const ClothSimulation::ClothMesh ClothSimulation::GetClothMesh() const {
return _cloth_mesh;
};

void ClothSimulation::move(const dtk::dtkDouble2& v) {
void ClothSimulation::move(const dtk::dtkDouble3& v) {
// Update camera position
g_camera_position += glm::vec3(v.x, v.y, v.z);

// Recalculate the ModelView matrix
g_ModelViewMatrix = glm::lookAt(
g_camera_position,
g_camera_target,
g_camera_up
) * glm::translate(glm::mat4(1), glm::vec3(0.0f, 0.0f, _param.w / 4));
};

void ClothSimulation::CleanUp() {
Expand Down Expand Up @@ -104,11 +112,15 @@ void ClothSimulation::InitCloth() {
}

void ClothSimulation::InitScene() {
g_camera_position = glm::vec3(0.618, -0.786, 0.3f) * g_camera_distance;
g_camera_target = glm::vec3(0.0f, 0.0f, -1.0f);
g_camera_up = glm::vec3(0.0f, 0.0f, 1.0f);

g_ModelViewMatrix = glm::lookAt(
glm::vec3(0.618, -0.786, 0.3f) * g_camera_distance,
glm::vec3(0.0f, 0.0f, -1.0f),
glm::vec3(0.0f, 0.0f, 1.0f)
) * glm::translate(glm::mat4(1), glm::vec3(0.0f, 0.0f, _param.w / 4));
g_camera_position,
g_camera_position + g_camera_target,
g_camera_up
);
g_ProjectionMatrix = glm::perspective(PI / 4.0f, g_windowWidth * 1.0f / g_windowHeight, 0.01f, 1000.0f);
};

Expand Down Expand Up @@ -143,9 +155,6 @@ void ClothSimulation::UpdateRenderTarget() {
const std::vector<dtk::dtkDouble3>& normalData = _cloth_mesh->GetVertexNormals();
float* normalBuffer = new float[vertexBufferSize];
for (dtk::dtkID i = 0;i < mPts->GetNumberOfPoints();i++) {
// vertexBuffer[3 * i + 0] = (float)mPts->GetPoint(i)[0];
// vertexBuffer[3 * i + 1] = (float)mPts->GetPoint(i)[1];
// vertexBuffer[3 * i + 2] = (float)mPts->GetPoint(i)[2];
normalBuffer[3 * i + 0] = (float)normalData[i].x;
normalBuffer[3 * i + 1] = (float)normalData[i].y;
normalBuffer[3 * i + 2] = (float)normalData[i].z;
Expand Down
Empty file.
23 changes: 14 additions & 9 deletions test/system_test/MassSpring3D/dtkPhysMassSpringSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,13 @@ void dtk::dtkPhysMassSpringSolver::step() {


void dtk::dtkPhysMassSpringSolver::satisfy(ClothDropType type) {
if (type == Sphere) {
const float radius = 0.64f;
const Eigen::Vector3f center(0, 0, -1);

auto satisfySphere = [&](const float& radius, const Eigen::Vector3f& center) {
#ifdef DTK_CUDA
int num_points = _system->GetNumberOfMassPoints();
size_t size = num_points * 3 * sizeof(float);
run_satisfy_sphere_with_cuda(d_current_state, num_points, radius, make_float3(center[0], center[1], center[2]));
cudaMemcpy(_current_state.data(), d_current_state, size, cudaMemcpyDeviceToHost);
#else
for (int i = 0; i < _system->GetNumberOfMassPoints(); i++) {
Vector3f p(
_current_state[3 * i + 0] - center[0],
Expand All @@ -248,10 +251,12 @@ void dtk::dtkPhysMassSpringSolver::satisfy(ClothDropType type) {
_current_state[3 * i + j] = p[j] + center[j];
}
}
}
else {
int fix_idx = 0;
for (int i = 0; i < 3; i++)
_current_state[fix_idx + i] = _initial_state[fix_idx + i];
#endif
};


if (type == Sphere) {
satisfySphere(0.64f, Eigen::Vector3f(-0.5, 0, -1));
satisfySphere(0.64f, Eigen::Vector3f(0, 0.5, -2));
}
}
6 changes: 5 additions & 1 deletion test/system_test/MassSpring3D/include/ClothSimulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ class ClothSimulation : public Scene {

const ClothMesh GetClothMesh() const;

void move(const dtk::dtkDouble2& v);
void move(const dtk::dtkDouble3& v);
void rotate_view(const float& deltaX, const float& deltaY);

void CleanUp();

Expand All @@ -95,6 +96,9 @@ class ClothSimulation : public Scene {
// Camera
dtk::dtkMatrix44 g_ModelViewMatrix;
dtk::dtkMatrix44 g_ProjectionMatrix;
glm::vec3 g_camera_position;
glm::vec3 g_camera_target;
glm::vec3 g_camera_up;
const float g_camera_distance = 4.2f;
const float PI = glm::pi<float>();

Expand Down
2 changes: 1 addition & 1 deletion test/system_test/MassSpring3D/include/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Scene {
virtual void Update(float dt) = 0;
virtual void Render() = 0;
virtual void CleanUp() = 0;
virtual void move(const dtk::dtkDouble2& v) = 0;
virtual void move(const dtk::dtkDouble3& v) = 0;

bool IsPause() const {
return State == SCENE_PAUSE;
Expand Down
6 changes: 6 additions & 0 deletions test/system_test/MassSpring3D/include/step.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@ void run_local_step_with_cuda(
const float* d_rest_lengths,
int num_springs
);
void run_satisfy_sphere_with_cuda(
float* d_current_state,
int num_points,
float radius,
float3 center
);
#endif // __LOCALSTEP_CUH__
28 changes: 21 additions & 7 deletions test/system_test/MassSpring3D/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ void display() {
draw_text(5, 40, "Push [1-1] to switch scene");
draw_text(w - 150, h - 20, "refer: apollonia");

draw_text(5, h - 60, "Mass Point: %d", I1_EDGE_NUM * I1_EDGE_NUM);
draw_text(5, h - 40, "%.2f FPS", fps);
if (current_scene->IsPause())
draw_text(5, h - 20, "dt: %.2f ms PAUSED", dt * 1000);
Expand All @@ -118,26 +119,37 @@ void reshape(int width, int height) {
gluPerspective(45.0, width / (float)height, 0.1, 100.0);
}

void mouse(int button, int state, int x, int y) {}

void move_pos(const dtk::dtkDouble2& v) { current_scene->move(v); }
void move_pos(const dtk::dtkDouble3& v) {
if (current_scene == nullptr) {
return;
}
current_scene->move(v);
}

void keyboard(unsigned char key, int x, int y) {
const float moveSpeed = 0.1f;
switch (key) {
case '1':
current_scene = new ClothSimulation(WINDOW_WIDTH, WINDOW_HEIGHT, { 0, -9.8 }, I1_EDGE_NUM);
move_pos(dtk::dtkDouble3(0, 0, 0));
break;
case 'w':
move_pos(dtk::dtkDouble2(0, 1));
move_pos(dtk::dtkDouble3(0, moveSpeed, 0)); // Move forward
break;
case 'a':
move_pos(dtk::dtkDouble2(-1, 0));
move_pos(dtk::dtkDouble3(-moveSpeed, 0, 0)); // Move left
break;
case 's':
move_pos(dtk::dtkDouble2(0, -1));
move_pos(dtk::dtkDouble3(0, -moveSpeed, 0)); // Move backward
break;
case 'd':
move_pos(dtk::dtkDouble2(1, 0));
move_pos(dtk::dtkDouble3(moveSpeed, 0, 0)); // Move right
break;
case 'q':
move_pos(dtk::dtkDouble3(0, 0, moveSpeed)); // Move up
break;
case 'e':
move_pos(dtk::dtkDouble3(0, 0, -moveSpeed)); // Move down
break;
case ' ':
current_scene->SetPause(!current_scene->IsPause());
Expand All @@ -150,6 +162,8 @@ void keyboard(unsigned char key, int x, int y) {
}
}

void mouse(int button, int state, int x, int y) {}

void motion(int x, int y) {}

void special(int key, int x, int y) {}
Expand Down
34 changes: 34 additions & 0 deletions test/system_test/MassSpring3D/step.cu
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,39 @@ void run_local_step_with_cuda(
);

// Wait for all threads to complete
cudaDeviceSynchronize();
}

extern "C" __global__ void satisfySphereKernel(float* current_state, int num_points, float radius, float3 center) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < num_points) {
float3 p = make_float3(
current_state[3 * i + 0] - center.x,
current_state[3 * i + 1] - center.y,
current_state[3 * i + 2] - center.z
);

float norm = sqrtf(p.x * p.x + p.y * p.y + p.z * p.z);
if (norm < radius) {
p.x /= norm;
p.y /= norm;
p.z /= norm;
p.x *= radius;
p.y *= radius;
p.z *= radius;

current_state[3 * i + 0] = p.x + center.x;
current_state[3 * i + 1] = p.y + center.y;
current_state[3 * i + 2] = p.z + center.z;
}
}
}

void run_satisfy_sphere_with_cuda(float* d_current_state, int num_points, float radius, float3 center) {
int blockSize = 256;
int numBlocks = (num_points + blockSize - 1) / blockSize;

satisfySphereKernel<<<numBlocks, blockSize>>>(d_current_state, num_points, radius, center);

cudaDeviceSynchronize();
}

0 comments on commit 575b54b

Please sign in to comment.