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