Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
491 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// | ||
// Beat.h | ||
// GravityBeats | ||
// | ||
// Created by Joshua Moerman on 1/9/13. | ||
// Copyright (c) 2013 Vadovas. All rights reserved. | ||
// | ||
|
||
#ifndef GravityBeats_Beat_h | ||
#define GravityBeats_Beat_h | ||
|
||
#include <vector> | ||
#include <cmath> | ||
|
||
#include "UserInformation.h" | ||
|
||
template <typename Information> | ||
struct Note : public UserInformation<Information>{ | ||
// see http://en.wikipedia.org/wiki/Note_value | ||
enum Speed { | ||
kWholeNote =1, // 1 in one measure | ||
kHalfNote =2, // 2 in one measure | ||
kTriplet =3, // 3 in one measure | ||
kQuarterNote =4, // 4 | ||
kHalfTriplet =6, // 6 | ||
kEighthNote =8 // 8 | ||
} speed; | ||
int progress = -2; | ||
|
||
template <typename... S> | ||
Note(Speed speed, S... args) | ||
: UserInformation<Information>(args...) | ||
, speed(speed) | ||
{} | ||
|
||
// we could return how much it is off, to give the balls the right initial position and speed. | ||
bool update(float time_in_measure){ | ||
int new_progress = std::floor(time_in_measure*speed); | ||
if(new_progress != progress){ | ||
if(progress == -2){ | ||
progress = new_progress; | ||
return false; | ||
} else { | ||
progress = new_progress; | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
void reset(){ | ||
progress = -1; | ||
} | ||
}; | ||
|
||
template <typename NoteInformation> | ||
struct Beat { | ||
float total_length{4.0}; // 60 bpm | ||
float time{-0.1}; | ||
|
||
std::vector<Note<NoteInformation>> notes; | ||
|
||
std::vector<NoteInformation> update(float dt){ | ||
std::vector<NoteInformation> ret; | ||
time += dt; | ||
|
||
// not needed, but keeps the floats small | ||
// also usefull when we want to change bpm | ||
if(time > total_length){ | ||
time -= total_length; | ||
for(auto& n : notes){ | ||
n.reset(); | ||
} | ||
} | ||
|
||
for(auto& n : notes){ | ||
if(n.update(time / total_length)){ | ||
ret.push_back(n.information); | ||
} | ||
} | ||
|
||
return ret; | ||
} | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// | ||
// Math.h | ||
// GravityBeats | ||
// | ||
// Created by Joshua Moerman on 1/12/13. | ||
// Copyright (c) 2013 Vadovas. All rights reserved. | ||
// | ||
|
||
#ifndef GravityBeats_Math_h | ||
#define GravityBeats_Math_h | ||
|
||
#include <cmath> | ||
|
||
namespace math { | ||
struct Vec2 { | ||
float x, y; | ||
|
||
Vec2& operator *= (float rh){ | ||
x *= rh; | ||
y *= rh; | ||
return *this; | ||
} | ||
|
||
Vec2& operator+= (Vec2 const & rh){ | ||
x += rh.x; | ||
y += rh.y; | ||
return *this; | ||
} | ||
|
||
float sqr_length() const { | ||
return x*x + y*y; | ||
} | ||
|
||
float length() const { | ||
return std::sqrt(sqr_length()); | ||
} | ||
|
||
Vec2& normalize(){ | ||
const float l = length(); | ||
if(l == 0.0f) { return *this; } | ||
x /= l; | ||
y /= l; | ||
return *this; | ||
} | ||
}; | ||
|
||
inline Vec2 operator*(float lh, Vec2 rh){ | ||
rh *= lh; | ||
return rh; | ||
} | ||
|
||
inline Vec2 operator+(Vec2 lh, Vec2 const & rh){ | ||
return lh += rh; | ||
} | ||
|
||
inline Vec2 operator-(Vec2 lh, Vec2 const & rh){ | ||
return lh += -1.0*rh; | ||
} | ||
|
||
inline float dot(Vec2 const & lh, Vec2 const & rh){ | ||
return lh.x*rh.x + lh.y*rh.y; | ||
} | ||
|
||
inline Vec2 rotate_ccw(Vec2 v){ | ||
std::swap(v.x, v.y); | ||
v.x *= -1.0; | ||
return v; | ||
} | ||
|
||
inline Vec2 normalize(Vec2 v){ | ||
return v.normalize(); | ||
} | ||
|
||
inline float distance_point_point(Vec2 p1, Vec2 p2){ | ||
return (p2 - p1).length(); | ||
} | ||
|
||
// p point, [v,w] line segment | ||
inline float distance_point_line(Vec2 p, Vec2 v, Vec2 w){ | ||
// http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment | ||
const float l2 = (v-w).sqr_length(); | ||
if (l2 == 0.0) return distance_point_point(p, v); | ||
|
||
const float t = dot(p - v, w - v) / l2; | ||
if (t < 0.0) return distance_point_point(p, v); | ||
else if (t > 1.0) return distance_point_point(p, w); | ||
|
||
auto projection = v + t * (w - v); | ||
return distance_point_point(p, projection); | ||
} | ||
|
||
template <typename T> | ||
constexpr T clamp(T input, T min, T max){ | ||
return input > max ? max : | ||
input < min ? min : input; | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// | ||
// Scales.h | ||
// GravityBeats | ||
// | ||
// Created by Joshua Moerman on 1/25/13. | ||
// Copyright (c) 2013 Vadovas. All rights reserved. | ||
// | ||
|
||
#ifndef GravityBeats_Scales_h | ||
#define GravityBeats_Scales_h | ||
|
||
#include <vector> | ||
#include <cmath> | ||
#include <iostream> | ||
#include <fstream> | ||
#include <stdexcept> | ||
|
||
// http://www.phys.unsw.edu.au/jw/notes.html | ||
|
||
inline float pitch_for_midi_note(int note){ | ||
// we say 440hz is 1 in our units | ||
float exponent = (note - 69) / 12.0f; | ||
return std::pow(2.0f, exponent); | ||
} | ||
|
||
struct Scale { | ||
std::vector<int> notes; | ||
|
||
int note_for_length(float length){ | ||
// determine note | ||
length /= 200.0; | ||
float note = -std::log(length) / std::log(2.0f) * 12.0f + 69.0f; | ||
|
||
// determine note in scale | ||
auto it = notes.begin(); | ||
while(*it < note && it != notes.end()){ | ||
++it; | ||
} | ||
|
||
// determine closest note in scale | ||
if(it == notes.begin()){ | ||
return *it; | ||
} else { | ||
auto it2 = it - 1; | ||
if(std::abs(*it - note) > std::abs(*it2 - note)){ | ||
return *it2; | ||
} else { | ||
return *it; | ||
} | ||
} | ||
} | ||
|
||
static Scale load_from_file(std::string filename){ | ||
std::ifstream file(filename); | ||
if(!file) throw std::runtime_error("Couldn't open file " + filename); | ||
|
||
Scale scale; | ||
|
||
int note = 0; | ||
while (file >> note) { | ||
scale.notes.push_back(note); | ||
} | ||
|
||
std::sort(scale.notes.begin(), scale.notes.end()); | ||
|
||
return scale; | ||
} | ||
}; | ||
|
||
#endif |
Oops, something went wrong.