Commit dcc6a9eb authored by bbguimaraes's avatar bbguimaraes
Browse files

sms: vector<T *> to vector<T> on SMS objects

parent d5b14441
......@@ -27,6 +27,8 @@ class Spring {
double eq_length() const {return this->m_eq_length;}
Vector distance() const {return this->m_distance;}
Vector force() const {return this->m_force;}
const Mass * mass0() const {return this->m_mass0;}
const Mass * mass1() const {return this->m_mass1;}
Mass * mass0() {return this->m_mass0;}
Mass * mass1() {return this->m_mass1;}
......
......@@ -3,28 +3,27 @@
#include <vector>
#include "sms/mass.h"
#include "sms/spring.h"
#include "sms/vector.h"
class Mass;
class Spring;
class SpringMassSystem {
static const float DAMPING;
std::vector<Mass *> m_masses;
std::vector<Spring *> m_springs;
std::vector<Mass> m_masses;
std::vector<Spring> m_springs;
Vector m_gravity;
public:
SpringMassSystem() : m_gravity(Vector(0.0f, -9.8f, 0.0f)) {}
void set_masses(const std::vector<Mass *> & m)
{this->m_masses = m;}
void set_springs(const std::vector<Spring *> & s)
{this->m_springs = s;}
void set_masses(const std::vector<Mass> & m) {this->m_masses = m;}
void set_springs(const std::vector<Spring> & s) {this->m_springs = s;}
void set_gravity(const Vector & g) {this->m_gravity = g;}
const std::vector<Mass *> * masses() const {return &this->m_masses;}
const std::vector<Spring *> * springs() const {return &this->m_springs;}
std::vector<Mass> * masses() {return &this->m_masses;}
std::vector<Spring> * springs() {return &this->m_springs;}
const std::vector<Mass> * masses() const {return &this->m_masses;}
const std::vector<Spring> * springs() const {return &this->m_springs;}
Vector gravity() const {return this->m_gravity;}
static void link(Mass * mass0, Mass * mass1, Spring * spring);
......
......@@ -16,19 +16,21 @@ void SpringMassSystem::link(Mass * mass0, Mass * mass1, Spring * spring) {
}
void SpringMassSystem::update(float interval) {
for(auto mass : *this->masses()) {
if(mass->fixed())
// TODO positions are updated while forces are being calculated
// TODO avoid calculating forces twice (related? ^)
for(auto & spring : *this->springs())
spring.update_force();
for(auto & mass : *this->masses()) {
if(mass.fixed())
continue;
Vector total_force = mass->force() + (this->m_gravity * mass->mass());
for(auto spring : *mass->springs())
total_force = total_force + (mass == spring->mass1()
Vector total_force = mass.force() + (this->m_gravity * mass.mass());
for(auto spring : *mass.springs())
total_force = total_force + (&mass == spring->mass1()
? spring->force()
: spring->force() * -1.0f);
Vector speed = mass->speed() + total_force / mass->mass();
Vector speed = mass.speed() + total_force / mass.mass();
speed = speed * this->DAMPING;
mass->set_speed(speed);
mass->set_position(mass->position() + speed * interval);
mass.set_speed(speed);
mass.set_position(mass.position() + speed * interval);
}
for(auto spring : *this->springs())
spring->update_force();
}
......@@ -60,9 +60,9 @@ class Display : public QGLWidget {
void draw_axis(float height);
void draw_circle(float radius);
void draw_system(SpringMassSystem * system);
void draw_springs_non_textured(SpringMassSystem * system);
void draw_springs_non_textured(const SpringMassSystem * system);
void draw_springs_textured(SpringMassSystem * system);
void draw_masses(SpringMassSystem * system, GLenum mode);
void draw_masses(const SpringMassSystem * system, GLenum mode);
void draw_hud();
void draw_number(unsigned int n);
void update_fps();
......
......@@ -104,7 +104,7 @@ void Display::select(Vector click) {
glPushName(0);
this->draw_masses(system, GL_SELECT);
if(glRenderMode(GL_RENDER) != 0) {
selected = (*system->masses())[select_buffer[3]];
selected = &(*system->masses())[select_buffer[3]];
break;
}
}
......@@ -189,14 +189,14 @@ void Display::draw_system(SpringMassSystem * system) {
this->draw_masses(system, GL_RENDER);
}
void Display::draw_springs_non_textured(SpringMassSystem * system) {
void Display::draw_springs_non_textured(const SpringMassSystem * system) {
glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT);
glLineWidth(5.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_LINES);
for(auto spring : *system->springs()) {
auto p0 = spring->mass0()->position();
auto p1 = spring->mass1()->position();
for(auto & spring : *system->springs()) {
auto p0 = spring.mass0()->position();
auto p1 = spring.mass1()->position();
glVertex3f(p0.x(), p0.y(), p0.z());
glVertex3f(p1.x(), p1.y(), p1.z());
}
......@@ -211,7 +211,7 @@ void Display::draw_springs_textured(SpringMassSystem * system) {
const float WIDTH_F = static_cast<float>(WIDTH);
auto point = [WIDTH, WIDTH_F, masses](int x, int y) {
glTexCoord2f(x / WIDTH_F, y / WIDTH_F);;
auto p = (*masses)[y * WIDTH + x]->position();
auto p = (*masses)[y * WIDTH + x].position();
glVertex3f(p.x(), p.y(), p.z());;
};
glEnable(GL_TEXTURE_2D);
......@@ -233,23 +233,23 @@ void Display::draw_springs_textured(SpringMassSystem * system) {
glDisable(GL_TEXTURE_2D);
}
void Display::draw_masses(SpringMassSystem * system, GLenum mode) {
void Display::draw_masses(const SpringMassSystem * system, GLenum mode) {
if(!this->m_quadric)
this->m_quadric = gluNewQuadric();
glPushAttrib(GL_CURRENT_BIT);
unsigned int index = 0;
for(auto mass : *system->masses()) {
for(auto & mass : *system->masses()) {
if(mode == GL_SELECT)
glLoadName(index++);
glPushMatrix();
if(mass == this->m_selected)
if(&mass == this->m_selected)
glColor3f(1.0f, 0.0f, 0.0f);
else
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef(
mass->position().x(),
mass->position().y(),
mass->position().z());
mass.position().x(),
mass.position().y(),
mass.position().z());
gluSphere(this->m_quadric, 0.1, 16, 16);
glPopMatrix();
}
......
......@@ -3,7 +3,6 @@
#include <QApplication>
#include <QTimer>
#include "sms/mass.h"
#include "sms/springmasssystem.h"
#include "smscreator.h"
......@@ -20,10 +19,10 @@ int main(int argc, char ** argv) {
SpringMassSystem sms0, sms1;
init_sm_system3(&sms0);
init_sm_system3(&sms1);
for(auto mass : *sms0.masses())
mass->set_position(mass->position() + Vector(-10.0f));
for(auto mass : *sms1.masses())
mass->set_position(mass->position() + Vector(10.0f));
for(auto & mass : *sms0.masses())
mass.set_position(mass.position() + Vector(-10.0f));
for(auto & mass : *sms1.masses())
mass.set_position(mass.position() + Vector(10.0f));
Display display;
display.makeCurrent();
display.set_texture(load_texture("texture.jpg"));
......@@ -60,7 +59,7 @@ void init_sm_system0(SpringMassSystem * system) {
"# spring k constant\n"
"0.25\n");
SMSCreator::read_from_file(system, &input);
(*system->masses())[0]->set_fixed(true);
(*system->masses())[0].set_fixed(true);
}
void init_sm_system1(SpringMassSystem * system) {
......@@ -69,7 +68,7 @@ void init_sm_system1(SpringMassSystem * system) {
Vector(),
Vector(5.0f, 0.0f, 0.0f),
10, 1, 1);
(*system->masses())[0]->set_fixed(true);
(*system->masses())[0].set_fixed(true);
}
void init_sm_system2(SpringMassSystem * system) {
......@@ -79,8 +78,8 @@ void init_sm_system2(SpringMassSystem * system) {
Vector(-5.0f, 10.0f), Vector(5.0f, 0.0f),
W, 5,
1.0f, 10.0f);
(*system->masses())[0]->set_fixed(true);
(*system->masses())[W - 1]->set_fixed(true);
(*system->masses())[0].set_fixed(true);
(*system->masses())[W - 1].set_fixed(true);
}
void init_sm_system3(SpringMassSystem * system) {
......@@ -90,8 +89,8 @@ void init_sm_system3(SpringMassSystem * system) {
Vector(-5.0f, 10.0f), Vector(5.0f, 0.0f),
W, 5,
1.0f, 10.0f);
(*system->masses())[0]->set_fixed(true);
(*system->masses())[W - 1]->set_fixed(true);
(*system->masses())[0].set_fixed(true);
(*system->masses())[W - 1].set_fixed(true);
}
GLuint load_texture(const std::string & filename) {
......
......@@ -57,25 +57,24 @@ void SMSCreator::create_string(
DIRECTION.magnitude() / static_cast<float>(n_masses - 1);
const auto INCREMENT_VECTOR = DIRECTION.normalized() * SPRING_LENGTH;
const auto EACH_MASS = total_mass / n_masses;
auto masses = std::vector<Mass *>(n_masses, nullptr);
auto springs = std::vector<Spring *>(n_masses - 1, nullptr);
auto masses = std::vector<Mass>(n_masses);
auto springs = std::vector<Spring>(n_masses - 1);
for(unsigned int i = 0; i < n_masses; ++i) {
auto mass = masses[i] = new Mass;
mass->set_mass(EACH_MASS);
mass->set_position(begin + (INCREMENT_VECTOR * static_cast<float>(i)));
auto & mass = masses[i];
mass.set_mass(EACH_MASS);
mass.set_position(begin + (INCREMENT_VECTOR * static_cast<float>(i)));
}
for(unsigned int i = 0; i < n_masses - 1; ++i) {
auto spring = springs[i] = new Spring;
spring->set_k(k);
spring->set_eq_length(SPRING_LENGTH);
for(auto & spring : springs) {
spring.set_k(k);
spring.set_eq_length(SPRING_LENGTH);
}
auto m0_it = std::begin(masses);
auto m1_it = ++std::begin(masses);
auto s_it = std::begin(springs);
while(m1_it != std::end(masses))
SpringMassSystem::link(*m0_it++, *m1_it++, *s_it++);
system->set_masses(masses);
system->set_springs(springs);
auto m0_it = std::begin(*system->masses());
auto m1_it = ++std::begin(*system->masses());
auto s_it = std::begin(*system->springs());
while(m1_it != std::end(*system->masses()))
SpringMassSystem::link(&(*m0_it++), &(*m1_it++), &(*s_it++));
}
/*static*/
......@@ -94,50 +93,41 @@ void SMSCreator::create_flag(
const float EACH_MASS = total_mass / N_MASSES;
const unsigned int N_SPRINGS =
x_masses * (y_masses - 1) + y_masses * (x_masses - 1);
auto masses = std::vector<Mass *>(N_MASSES);
auto springs = std::vector<Spring *>(N_SPRINGS);
for(unsigned int i = 0; i < N_MASSES; ++i)
for(unsigned int i = 0; i < N_SPRINGS; ++i) {
auto spring = springs[i] = new Spring;
spring->set_k(k);
}
auto masses = std::vector<Mass>(N_MASSES);
auto springs = std::vector<Spring>(N_SPRINGS);
for(auto & spring : springs)
spring.set_k(k);
for(unsigned int y = 0; y < y_masses; ++y) {
for(unsigned int x = 0; x < x_masses; ++x) {
auto mass = masses[index(x, y)] = new Mass;
mass->set_mass(EACH_MASS);
mass->set_position(
auto & mass = masses[index(x, y)];
mass.set_mass(EACH_MASS);
mass.set_position(
begin + Vector(x * INCREMENT.x(), y * INCREMENT.y()));
}
}
auto spring_it = std::begin(springs);
system->set_masses(masses);
system->set_springs(springs);
auto spring_it = std::begin(*system->springs());
auto link = [system, index, &spring_it](\
unsigned int x0, unsigned int y0,
unsigned int x1, unsigned int y1,
float eq_length) {
spring_it->set_eq_length(std::abs(eq_length));
SpringMassSystem::link(
&(*system->masses())[index(x0, y0)],
&(*system->masses())[index(x1, y1)],
&(*spring_it));
++spring_it;
};
for(unsigned int y = 0; y < y_masses - 1; ++y) {
for(unsigned int x = 0; x < x_masses - 1; ++x) {
(*spring_it)->set_eq_length(std::abs(INCREMENT.x()));
SpringMassSystem::link(
masses[index(x , y)],
masses[index(x + 1, y)],
*spring_it++);
(*spring_it)->set_eq_length(std::abs(INCREMENT.y()));
SpringMassSystem::link(
masses[index(x, y )],
masses[index(x, y + 1)],
*spring_it++);
link(x, y, x + 1, y , INCREMENT.x());
link(x, y, x , y + 1, INCREMENT.y());
}
(*spring_it)->set_eq_length(std::abs(INCREMENT.y()));
SpringMassSystem::link(
masses[index(x_masses - 1, y)],
masses[index(x_masses - 1, y + 1)],
*spring_it++);
}
for(unsigned int x = 0; x < x_masses - 1; ++x) {
(*spring_it)->set_eq_length(std::abs(INCREMENT.x()));
SpringMassSystem::link(
masses[index(x , y_masses - 1)],
masses[index(x + 1, y_masses - 1)],
*spring_it++);
link(x_masses - 1, y, x_masses - 1, y + 1, INCREMENT.y());
}
system->set_masses(masses);
system->set_springs(springs);
for(unsigned int x = 0; x < x_masses - 1; ++x)
link(x, y_masses - 1, x + 1, y_masses - 1, INCREMENT.x());
}
void SMSCreator::create_crossed_flag(
......@@ -157,31 +147,31 @@ void SMSCreator::create_crossed_flag(
const unsigned int N_SPRINGS =
(x_masses * (y_masses - 1) + y_masses * (x_masses - 1))
+ (2 * (x_masses - 1) * (y_masses - 1));
auto masses = std::vector<Mass *>(N_MASSES);
auto springs = std::vector<Spring *>(N_SPRINGS);
for(unsigned int i = 0; i < N_MASSES; ++i)
for(unsigned int i = 0; i < N_SPRINGS; ++i) {
auto spring = springs[i] = new Spring;
spring->set_k(k);
}
auto masses = std::vector<Mass>(N_MASSES);
auto springs = std::vector<Spring>(N_SPRINGS);
for(unsigned int y = 0; y < y_masses; ++y) {
for(unsigned int x = 0; x < x_masses; ++x) {
auto mass = masses[index(x, y)] = new Mass;
mass->set_mass(EACH_MASS);
mass->set_position(
auto & mass = masses[index(x, y)];
mass.set_mass(EACH_MASS);
mass.set_position(
begin + Vector(x * INCREMENT.x(), y * INCREMENT.y()));
}
}
auto spring_it = std::begin(springs);
auto link = [masses, index, &spring_it](\
for(auto & spring : springs)
spring.set_k(k);
system->set_masses(masses);
system->set_springs(springs);
auto spring_it = std::begin(*system->springs());
auto link = [system, index, &spring_it](\
unsigned int x0, unsigned int y0,
unsigned int x1, unsigned int y1,
float eq_length) {
(*spring_it)->set_eq_length(std::abs(eq_length));
spring_it->set_eq_length(std::abs(eq_length));
SpringMassSystem::link(
masses[index(x0, y0)],
masses[index(x1, y1)],
*spring_it++);
&(*system->masses())[index(x0, y0)],
&(*system->masses())[index(x1, y1)],
&(*spring_it));
++spring_it;
};
for(unsigned int y = 0; y < y_masses - 1; ++y) {
for(unsigned int x = 0; x < x_masses - 1; ++x) {
......@@ -192,13 +182,6 @@ void SMSCreator::create_crossed_flag(
}
link(x_masses - 1, y, x_masses - 1, y + 1, INCREMENT.y());
}
for(unsigned int x = 0; x < x_masses - 1; ++x) {
(*spring_it)->set_eq_length(std::abs(INCREMENT.x()));
SpringMassSystem::link(
masses[index(x , y_masses - 1)],
masses[index(x + 1, y_masses - 1)],
*spring_it++);
}
system->set_masses(masses);
system->set_springs(springs);
for(unsigned int x = 0; x < x_masses - 1; ++x)
link(x, y_masses - 1, x + 1, y_masses - 1, INCREMENT.x());
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment