From 5ecd92dd7111c9ea7d0fb0cafd02f60d1d9093a3 Mon Sep 17 00:00:00 2001 From: Yuwei Xiao <xyw1105@126.com> Date: Wed, 8 Apr 2020 12:18:35 +0800 Subject: [PATCH] ex4 --- {4_collision => 4-1_spinning}/CMakeLists.txt | 2 +- 4-1_spinning/SpinSim.cpp | 28 +++++++ 4-1_spinning/SpinSim.h | 73 ++++++++++++++++++ 4-1_spinning/main.cpp | 77 +++++++++++++++++++ 4-2_collision/CMakeLists.txt | 43 +++++++++++ .../CollisionDetection.cpp | 0 .../CollisionDetection.h | 0 {4_collision => 4-2_collision}/CollisionSim.h | 0 {4_collision => 4-2_collision}/main.cpp | 0 CMakeLists.txt | 8 +- 10 files changed, 227 insertions(+), 4 deletions(-) rename {4_collision => 4-1_spinning}/CMakeLists.txt (98%) create mode 100644 4-1_spinning/SpinSim.cpp create mode 100644 4-1_spinning/SpinSim.h create mode 100644 4-1_spinning/main.cpp create mode 100644 4-2_collision/CMakeLists.txt rename {4_collision => 4-2_collision}/CollisionDetection.cpp (100%) rename {4_collision => 4-2_collision}/CollisionDetection.h (100%) rename {4_collision => 4-2_collision}/CollisionSim.h (100%) rename {4_collision => 4-2_collision}/main.cpp (100%) diff --git a/4_collision/CMakeLists.txt b/4-1_spinning/CMakeLists.txt similarity index 98% rename from 4_collision/CMakeLists.txt rename to 4-1_spinning/CMakeLists.txt index f2a3b20..fca18b9 100644 --- a/4_collision/CMakeLists.txt +++ b/4-1_spinning/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.1) -project(4_collision) +project(4-1_spinning) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) set(CMAKE_CXX_FLAGS "-Wall") diff --git a/4-1_spinning/SpinSim.cpp b/4-1_spinning/SpinSim.cpp new file mode 100644 index 0000000..c53e4ad --- /dev/null +++ b/4-1_spinning/SpinSim.cpp @@ -0,0 +1,28 @@ +#include "SpinSim.h" + +bool SpinSim::advance() { + Eigen::Vector3d w = p_body->getAngularVelocity(); + + // TODO + // update orientation + switch (m_method) { + case 0: { + // matrix-based angular velocity + break; + } + + case 1: { + // quaternion-based angular velocity + break; + } + default: + std::cerr << m_method << " is not a valid rotation method." + << std::endl; + } + + // advance time + m_time += m_dt; + m_step++; + + return false; +} \ No newline at end of file diff --git a/4-1_spinning/SpinSim.h b/4-1_spinning/SpinSim.h new file mode 100644 index 0000000..268e41e --- /dev/null +++ b/4-1_spinning/SpinSim.h @@ -0,0 +1,73 @@ +#include "Simulation.h" + +using namespace std; + +/* + */ +class SpinSim : public Simulation { + public: + SpinSim() : Simulation() { init(); } + + virtual void init() override { + std::string file = "cube.off"; + + m_objects.clear(); + m_objects.push_back(RigidObject(file)); + p_body = &m_objects.back(); + + m_dt = 1e-3; + + reset(); + } + + virtual void resetMembers() override { + p_body->reset(); + p_body->setMass(m_mass); + + p_body->applyForce(m_force, Eigen::Vector3d(1, 1, 1)); + p_body->applyForce(-m_force, Eigen::Vector3d(-1, -1, -1)); + + // compute linear and angular momentums + p_body->setLinearMomentum(p_body->getLinearMomentum() + + m_dt * p_body->getForce()); + p_body->setAngularMomentum(p_body->getAngularMomentum() + + m_dt * p_body->getTorque()); + p_body->resetForce(); + p_body->resetTorque(); + } + + virtual void updateRenderGeometry() override { + p_body->getMesh(m_renderV, m_renderF); + } + + virtual bool advance() override; + + virtual void renderRenderGeometry( + igl::opengl::glfw::Viewer &viewer) override { + viewer.data().set_mesh(m_renderV, m_renderF); + viewer.data().compute_normals(); + } + +#pragma region SettersAndGetters + void setForce(const Eigen::Vector3d &f) { m_force = f; } + + void setMass(double m) { m_mass = m; } + + void setMethod(int m) { m_method = m; } + + Eigen::Vector3d getRotationalEnergy() { + return 0.5 * p_body->getInertia().diagonal().cwiseProduct( + p_body->getAngularVelocity()); + } +#pragma endregion SettersAndGetters + + private: + double m_mass; + Eigen::Vector3d m_force; + int m_method = 0; + + RigidObject *p_body; + + Eigen::MatrixXd m_renderV; // vertex positions for rendering + Eigen::MatrixXi m_renderF; // face indices for rendering +}; \ No newline at end of file diff --git a/4-1_spinning/main.cpp b/4-1_spinning/main.cpp new file mode 100644 index 0000000..c8bac60 --- /dev/null +++ b/4-1_spinning/main.cpp @@ -0,0 +1,77 @@ +#include <deque> +#include "Gui.h" +#include "Simulator.h" +#include "SpinSim.h" + +class SpinGui : public Gui { + public: + // simulation parameters + Eigen::Vector3f m_force; + float m_mass = 1.0; + float m_dt = 1e-3; + int m_maxHistory = 200; + std::vector<float> m_energy_history; + + const vector<char const *> m_methods = {"Matrix", "Quaternion"}; + int m_selected_method = 0; + + SpinSim *p_spinSim = NULL; + + SpinGui() { + m_force << 10000, 0, 0; + m_energy_history.clear(); + + p_spinSim = new SpinSim(); + p_spinSim->setForce(m_force.cast<double>()); + p_spinSim->setMass(m_mass); + setSimulation(p_spinSim); + + // show vertex velocity instead of normal + callback_clicked_vertex = + [&](int clickedVertexIndex, int clickedObjectIndex, + Eigen::Vector3d &pos, Eigen::Vector3d &dir) { + RigidObject &o = p_spinSim->getObjects()[clickedObjectIndex]; + pos = o.getVertexPosition(clickedVertexIndex); + dir = o.getVelocity(pos); + }; + start(); + } + + virtual void updateSimulationParameters() override { + // change all parameters of the simulation to the values that are set in + // the GUI + p_spinSim->setForce(m_force.cast<double>()); + p_spinSim->setMass(m_mass); + p_spinSim->setTimestep(m_dt); + p_spinSim->setMethod(m_selected_method); + } + + virtual void drawSimulationParameterMenu() override { + ImGui::Combo("Method", &m_selected_method, m_methods.data(), + m_methods.size()); + ImGui::InputFloat3("Force", m_force.data(), 0); + ImGui::InputFloat("Mass", &m_mass, 0, 0, 6); + ImGui::InputFloat("dt", &m_dt, 0, 0); + } + + virtual void drawSimulationStats() override { + Eigen::Vector3d E = p_spinSim->getRotationalEnergy(); + m_energy_history.push_back(E.cast<float>().cwiseAbs().sum()); + if (m_energy_history.size() > m_maxHistory) + m_energy_history.erase(m_energy_history.begin(), + m_energy_history.begin() + 1); + ImGui::Text("E_x: %.3f", E(0)); + ImGui::Text("E_y: %.3f", E(1)); + ImGui::Text("E_z: %.3f", E(2)); + ImGui::PlotLines("Total Energy", &m_energy_history[0], + m_energy_history.size(), 0, NULL, 0, 1000, + ImVec2(0, 200)); + } +}; + +int main(int argc, char *argv[]) { + // create a new instance of the GUI for the spinning simulation + new SpinGui(); + + return 0; +} \ No newline at end of file diff --git a/4-2_collision/CMakeLists.txt b/4-2_collision/CMakeLists.txt new file mode 100644 index 0000000..f4bc44c --- /dev/null +++ b/4-2_collision/CMakeLists.txt @@ -0,0 +1,43 @@ + +cmake_minimum_required(VERSION 3.1) +project(4-2_collision) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) +set(CMAKE_CXX_FLAGS "-Wall") + +# libigl +option(LIBIGL_USE_STATIC_LIBRARY "Use libigl as static library" OFF) +option(LIBIGL_WITH_ANTTWEAKBAR "Use AntTweakBar" OFF) +option(LIBIGL_WITH_CGAL "Use CGAL" OFF) +option(LIBIGL_WITH_COMISO "Use CoMiso" OFF) +option(LIBIGL_WITH_CORK "Use Cork" OFF) +option(LIBIGL_WITH_EMBREE "Use Embree" OFF) +option(LIBIGL_WITH_LIM "Use LIM" OFF) +option(LIBIGL_WITH_MATLAB "Use Matlab" OFF) +option(LIBIGL_WITH_MOSEK "Use MOSEK" OFF) +option(LIBIGL_WITH_OPENGL "Use OpenGL" ON) +option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON) +option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON) +option(LIBIGL_WITH_PNG "Use PNG" OFF) +option(LIBIGL_WITH_PYTHON "Use Python" OFF) +option(LIBIGL_WITH_TETGEN "Use Tetgen" OFF) +option(LIBIGL_WITH_TRIANGLE "Use Triangle" OFF) +option(LIBIGL_WITH_VIEWER "Use OpenGL viewer" ON) +option(LIBIGL_WITH_XML "Use XML" OFF) + +if (NOT LIBIGL_FOUND) + find_package(LIBIGL REQUIRED QUIET) +endif() + +# Add default project files +file(GLOB LIBFILES ${PROJECT_SOURCE_DIR}/../include/*.*) +source_group("Library Files" FILES ${LIBFILES}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) + +# Add your project files +file(GLOB SRCFILES *.cpp) +file(GLOB HFILES *.h) + +add_definitions(-DIGL_VIEWER_VIEWER_QUIET) +add_executable(${PROJECT_NAME} ${SRCFILES} ${HFILES} ${LIBFILES} ) +target_link_libraries(${PROJECT_NAME} igl::core igl::opengl_glfw igl::opengl_glfw_imgui) \ No newline at end of file diff --git a/4_collision/CollisionDetection.cpp b/4-2_collision/CollisionDetection.cpp similarity index 100% rename from 4_collision/CollisionDetection.cpp rename to 4-2_collision/CollisionDetection.cpp diff --git a/4_collision/CollisionDetection.h b/4-2_collision/CollisionDetection.h similarity index 100% rename from 4_collision/CollisionDetection.h rename to 4-2_collision/CollisionDetection.h diff --git a/4_collision/CollisionSim.h b/4-2_collision/CollisionSim.h similarity index 100% rename from 4_collision/CollisionSim.h rename to 4-2_collision/CollisionSim.h diff --git a/4_collision/main.cpp b/4-2_collision/main.cpp similarity index 100% rename from 4_collision/main.cpp rename to 4-2_collision/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d67a197..fa70829 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ endif() # add_subdirectory(1-0_earth) # add_subdirectory(1-1_cannonball) # add_subdirectory(1-2_spring) -add_subdirectory(2-1_bead) -add_subdirectory(2-2_pendulum) -add_subdirectory(3_cloth) \ No newline at end of file +# add_subdirectory(2-1_bead) +# add_subdirectory(2-2_pendulum) +# add_subdirectory(3_cloth) +add_subdirectory(4-1_spinning) +add_subdirectory(4-2_collision) \ No newline at end of file -- GitLab