Browse Source

Added simulation :D

master
Joshua Moerman 11 years ago
parent
commit
38db5fded3
  1. 2
      simulation
  2. 92
      src/app.h
  3. 36
      src/main.cpp

2
simulation

@ -1 +1 @@
Subproject commit 018cb176c4b3970cd2a6ecae8a63520183c5ddd3
Subproject commit 61c889b0c697f522a66a7bfaf002cd143d018060

92
src/app.h

@ -1,42 +1,102 @@
#pragma once
#include <iostream>
#include <cstdlib>
#include <chrono>
#include <cmath>
#include <vector>
#include <algorithm>
#include "basics.h"
#include "adaptions.h"
#include "simulation/Simulation.h"
#include "simulation/Beat.h"
using Vec2 = math::Vec2;
using LineKind = simulation::LineKind;
using ball_info = int;
using line_info = void;
using ball_type = simulation::Ball<ball_info>;
using line_type = simulation::Line<line_info>;
using simu_type = simulation::Simulation<ball_info, line_info>;
using note_info = Vec2;
using note_type = Note<note_info>;
using beat_type = Beat<note_info>;
struct AbstractLine {
math::Vec2 starting_point;
math::Vec2 end_point;
LineKind line_kind;
const float hsize = 5.0f;
AbstractLine(math::Vec2 starting_point, math::Vec2 end_point, LineKind line_kind)
: starting_point(starting_point)
, end_point(end_point)
, line_kind(line_kind)
{}
// create 6 lines, to emulate width, and rounded edges
std::vector<line_type> calculate_lines() const {
auto dir = normalize(end_point - starting_point);
auto normal = rotate_ccw(dir);
if(line_kind == simulation::kOneWay){
std::vector<line_type> ret;
ret.emplace_back(starting_point + hsize*normal, end_point + hsize*normal, line_kind);
ret.emplace_back(end_point + hsize*normal, end_point + hsize*dir, line_kind);
ret.emplace_back(end_point + hsize*dir, end_point - hsize*normal, line_kind);
ret.emplace_back(end_point - hsize*normal, starting_point - hsize*normal, line_kind);
ret.emplace_back(starting_point - hsize*normal, starting_point - hsize*dir, line_kind);
ret.emplace_back(starting_point - hsize*dir, starting_point + hsize*normal, line_kind);
return ret;
} else {
std::vector<line_type> ret;
ret.emplace_back(starting_point, end_point, line_kind);
return ret;
}
}
};
struct libwebsocket;
struct App{
std::vector<User*> people_online;
int uid{0};
libwebsocket * uberclient{nullptr};
void update_positions(){
const float speed = 0.4;
simu_type sim;
beat_type beat;
typedef std::chrono::duration<double, std::ratio<1,1>> fseconds;
static auto start = std::chrono::steady_clock::now();
auto end = std::chrono::steady_clock::now();
double time = std::chrono::duration_cast<fseconds>(end-start).count();
const float iframerate = 1.0/60.0;
int peopleuid{0};
int balluid{0};
//std::cout << time << std::endl;
auto n = people_online.size();
for(int i = 0; i < n; ++i){
User& user = *people_online[i];
double x = cos(speed * time + 2*M_PI*i/double(n));
double y = sin(speed * time + 2*M_PI*i/double(n));
App(){
beat.notes.emplace_back(note_type::kQuarterNote, note_info{100.0f, 100.0f});
user.position.x = 200 + 200*x;
user.position.y = 200 + 200*y;
AbstractLine line(Vec2{50.0f, 100.0f}, Vec2{150.0f, 200.0f}, simulation::kOneWay);
for(auto & l : line.calculate_lines()){
sim.lines.push_back(l);
}
}
void login(User& user){
user.index = uid++;
user.index = peopleuid++;
people_online.push_back(&user);
}
void logout(User& user){
people_online.erase(std::remove(people_online.begin(), people_online.end(), &user), people_online.end());
}
void update(){
float dt = iframerate;
sim.update(dt);
for(auto n : beat.update(dt)){
sim.balls.emplace_back(n.x, n.y, 0, 0, balluid++);
}
}
};

36
src/main.cpp

@ -26,9 +26,12 @@ websockets::TestProtocol<User> default_protocol{
app->logout(user);
},
// write (will always come after receive)
app->update_positions();
return write_json(ptrvector_to_json(app->people_online));
[](User& user, basic_websocket_info) -> std::string{
js::Object ret;
ret["people"] = ptrvector_to_json(app->people_online);
ret["balls"] = vector_to_json(app->sim.balls);
ret["lines"] = vector_to_json(app->sim.lines);
return write_json(ret);
},
// receive
[](User& user, std::string in, basic_websocket_info){
@ -46,9 +49,31 @@ websockets::TestProtocol<Empty> observer_protocol{
// connection closed
[](Empty& user, basic_websocket_info){},
// write (will always come after receive)
app->update_positions();
return write_json(ptrvector_to_json(app->people_online));
[](Empty& user, basic_websocket_info) -> std::string{
js::Object ret;
ret["people"] = ptrvector_to_json(app->people_online);
ret["balls"] = vector_to_json(app->sim.balls);
ret["lines"] = vector_to_json(app->sim.lines);
return write_json(ret);
},
// receive
[](Empty& user, std::string in, basic_websocket_info){}
};
websockets::TestProtocol<Empty> uberclient_protocol{
// connection established
[](Empty& user, basic_websocket_info binfo){
if(app->uberclient) throw websockets::runtime_error("Warning: another uberclient connection\n");
app->uberclient = binfo.wsi;
},
// connection closed
[](Empty& user, basic_websocket_info){
app->uberclient = nullptr;
},
// write (will always come after receive)
[](Empty& user, basic_websocket_info) -> std::string{
static int i = 0;
return std::to_string(i++);
},
// receive
[](Empty& user, std::string in, basic_websocket_info){}
@ -60,8 +85,9 @@ int main(int argc, char **argv){
libwebsocket_protocols protocols[] = {
WSstandard_protocol("default", default_protocol),
WSstandard_protocol("observer", observer_protocol),
WSstandard_protocol("uberclient", uberclient_protocol),
{ NULL, NULL, 0 } // end of list
};
return websockets::default_main(argc, argv, protocols);
return websockets::default_main(argc, argv, protocols, []{app->update();});
}