Skip to content

Commit 05855d8

Browse files
committed
Add scaffolding for Kelvinlet implementation
1 parent c7c8373 commit 05855d8

File tree

14 files changed

+1040
-3442
lines changed

14 files changed

+1040
-3442
lines changed

.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,26 @@
1+
# OS X Finder
12
.DS_Store
3+
4+
# Xcode per-user config
5+
*.mode1
6+
*.mode1v3
7+
*.mode2v3
8+
*.perspective
9+
*.perspectivev3
10+
*.pbxuser
11+
*.xcworkspace
12+
xcuserdata
13+
14+
# Build products
15+
build/
216
bin/*
17+
*.o
18+
*.LinkFileList
19+
*.hmap
20+
21+
# Automatic backup files
22+
*~.nib/
23+
*.swp
24+
*~
25+
*.dat
26+
*.dep

DynamicKelvinlets.xcodeproj/project.pbxproj

Lines changed: 867 additions & 3416 deletions
Large diffs are not rendered by default.

DynamicKelvinlets.xcodeproj/project.xcworkspace/contents.xcworkspacedata

Lines changed: 0 additions & 7 deletions
This file was deleted.

DynamicKelvinlets.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

Lines changed: 0 additions & 8 deletions
This file was deleted.

DynamicKelvinlets.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/DisplacedMesh.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "DisplacedMesh.h"
2+
3+
DisplacedMesh::DisplacedMesh(ofMesh mesh, Material material):
4+
mesh(mesh),
5+
material(material),
6+
currentTime(0),
7+
originalPositions(mesh.getVertices())
8+
{}
9+
10+
void DisplacedMesh::update(float elapsedTime) {
11+
currentTime += elapsedTime;
12+
13+
// TODO remove kelvinlets with no influence
14+
15+
mesh.getVertices() = originalPositions;
16+
17+
// Take the superposition of offsets from all applied Kelvinlets
18+
for (auto& kelvinlet: kelvinlets) {
19+
vector<glm::vec3> offsets = kelvinlet.displacements(material, currentTime);
20+
for (size_t i = 0; i < mesh.getNumVertices(); i++) {
21+
mesh.setVertex(i, mesh.getVertex(i) + offsets[i]);
22+
}
23+
}
24+
}
25+
26+
void DisplacedMesh::addKelvinlet(Kelvinlet kelvinlet) {
27+
kelvinlets.push_back(DisplacedMesh::TimeShiftedKelvinlet{
28+
.kelvinlet=kelvinlet,
29+
.t0=currentTime,
30+
.initialLocations=mesh.getVertices()
31+
});
32+
}
33+
34+
void DisplacedMesh::draw() const {
35+
mesh.draw();
36+
}
37+
38+
void DisplacedMesh::drawWireframe() const {
39+
mesh.drawWireframe();
40+
}
41+
42+
vector<glm::vec3> DisplacedMesh::TimeShiftedKelvinlet::displacements(Material material, float t) const {
43+
vector<glm::vec3> result;
44+
45+
// Apply displacements to every point
46+
for (auto& point : initialLocations) {
47+
result.push_back(kelvinlet.displacementRK4(point, material, t - t0));
48+
}
49+
50+
return result;
51+
}

src/DisplacedMesh.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include "ofMain.h"
4+
#include "Kelvinlet.h"
5+
6+
class DisplacedMesh {
7+
public:
8+
DisplacedMesh(ofMesh mesh, Material material);
9+
void update(float elapsedTime);
10+
void addKelvinlet(Kelvinlet kelvinlet);
11+
void draw() const;
12+
void drawWireframe() const;
13+
14+
private:
15+
// Because Kelvinlets measure distances from their centers to points at the time
16+
// of the force's application, we need to save the location of the mesh's vertices
17+
// at the time of force application.
18+
struct TimeShiftedKelvinlet {
19+
Kelvinlet kelvinlet;
20+
float t0;
21+
vector<glm::vec3> initialLocations;
22+
23+
vector<glm::vec3> displacements(Material material, float t) const;
24+
};
25+
26+
ofMesh mesh;
27+
Material material;
28+
float currentTime;
29+
vector<glm::vec3> originalPositions;
30+
vector<TimeShiftedKelvinlet> kelvinlets;
31+
};

src/Kelvinlet.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "Kelvinlet.h"
2+
3+
#include <algorithm>
4+
5+
glm::vec3 Kelvinlet::displacementRK4(glm::vec3 position, Material material, float t) const {
6+
glm::vec3 v0 = displacement(position, material, t);
7+
glm::vec3 v1 = displacement(position + 0.5*v0, material, t);
8+
glm::vec3 v2 = displacement(position + 0.5*v1, material, t);
9+
glm::vec3 v3 = displacement(position + v2, material, t);
10+
11+
return (v0 + v1*2 + v2*2 + v3) / 6;
12+
}
13+
14+
glm::vec3 Kelvinlet::displacement(glm::vec3 position, Material material, float t) const {
15+
// No influence at all if the impulse hasn't happened yet
16+
if (t < 0) return {0,0,0};
17+
18+
// TODO do actual calculation here
19+
return {0,0,0};
20+
}

src/Kelvinlet.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "ofMain.h"
4+
#include "Material.h"
5+
6+
struct Kelvinlet {
7+
glm::vec3 force;
8+
glm::vec3 center;
9+
float scale;
10+
11+
glm::vec3 displacementRK4(glm::vec3 position, Material material, float t) const;
12+
13+
private:
14+
glm::vec3 displacement(glm::vec3 position, Material material, float t) const;
15+
};

src/Material.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "Material.h"
2+
#include "ofMain.h"
3+
4+
// Stiffness is μ in Eq. 1
5+
// Compressibility is v in Eq. 1
6+
Material::Material(float stiffness, float compressibility):
7+
beta(sqrt(stiffness)),
8+
alpha(beta * sqrt(1.0 + 1.0/(1.0 - 2.0*compressibility)))
9+
{}

src/Material.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
3+
struct Material {
4+
Material(float stiffness, float compressibility);
5+
6+
float beta;
7+
float alpha;
8+
};

src/ofApp.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ constexpr unsigned int H = 20;
55

66
//--------------------------------------------------------------
77
void ofApp::setup() {
8+
ofMesh mesh;
9+
810
auto coordToIndex = [=](unsigned int x, unsigned int y) { return y * W + x; };
911

1012
for (unsigned int x = 0; x < W; x++) {
@@ -18,10 +20,19 @@ void ofApp::setup() {
1820
}
1921
}
2022
}
23+
24+
displacedMesh = make_shared<DisplacedMesh>(mesh, Material(5, 0.45));
25+
displacedMesh->addKelvinlet(Kelvinlet{
26+
.force = {0, 2, 0},
27+
.center = {W/2, H/2, 0},
28+
.scale = 1
29+
});
2130
}
2231

2332
//--------------------------------------------------------------
24-
void ofApp::update() {}
33+
void ofApp::update() {
34+
displacedMesh->update(ofGetLastFrameTime());
35+
}
2536

2637
//--------------------------------------------------------------
2738
void ofApp::draw() {
@@ -32,7 +43,7 @@ void ofApp::draw() {
3243
ofPushMatrix();
3344
ofTranslate(WINDOW_WIDTH / 2 - scale * W / 2, WINDOW_HEIGHT / 2 - scale * H / 2);
3445
ofScale(scale);
35-
mesh.drawWireframe();
46+
displacedMesh->drawWireframe();
3647
ofPopMatrix();
3748
}
3849

src/ofApp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "ofMain.h"
4+
#include "DisplacedMesh.h"
45

56
constexpr unsigned int WINDOW_WIDTH = 1024;
67
constexpr unsigned int WINDOW_HEIGHT = 768;
@@ -25,5 +26,5 @@ class ofApp : public ofBaseApp {
2526
void gotMessage(ofMessage msg);
2627

2728
private:
28-
ofMesh mesh;
29+
shared_ptr<DisplacedMesh> displacedMesh;
2930
};

0 commit comments

Comments
 (0)