123 lines
3.4 KiB
C++
123 lines
3.4 KiB
C++
#include "beatlevelrenderhelperimpl.h"
|
|
|
|
#include "beatmap.h"
|
|
|
|
#include <iostream> //debug only
|
|
|
|
#include <cmath>
|
|
|
|
// Lookup table for rotations of notes based on type nummber
|
|
static const float ROTLOOKUP[] {
|
|
0, // 0 (from top)
|
|
M_PI, // 1 (from bottom)
|
|
-M_PI_2, // 2 Left
|
|
M_PI_2, // 3 Right
|
|
-M_PI_4, // 4 Up Left
|
|
M_PI_4, // 5 Up Right
|
|
-M_PI_4 * 3, // 6 Down Left
|
|
M_PI_4 * 3, // 7 Down Right
|
|
0 // 8 Any (Dot Note)
|
|
};
|
|
|
|
namespace Beatsaber {
|
|
|
|
//TODO: make configureble
|
|
static const uint32_t LINECOUNT = 4;
|
|
static const uint32_t LAYERCOUNT = 3;
|
|
static const double LINESPACING = 0.6;
|
|
static const double LAYERSPACING = 0.6;
|
|
static const double LAYEROFFSET = 0.6;
|
|
static const double LINEOFFSET = LINESPACING/2;
|
|
|
|
static const double RENDERDISTANCE = 100; // block spawn distance (spawn point - player position) in m
|
|
|
|
BeatLevelRenderHelperImpl::BeatLevelRenderHelperImpl(std::shared_ptr<const BeatLevel> level) : level(level) {
|
|
bps = level->getBeatMap()->getBPM() / 60.0;
|
|
njs = level->getNoteJumpSpeed();
|
|
double offset = level->getNoteStartOffset();
|
|
|
|
jumpDuration = RENDERDISTANCE/njs;
|
|
jumpDistance = offset + RENDERDISTANCE/2;
|
|
|
|
//copy notes into map
|
|
const std::vector<Note>& originalNotes = level->getNotes();
|
|
auto itHint = notes.begin();
|
|
for(const Note& n : originalNotes) {
|
|
itHint = notes.insert(itHint, {n.time, n});
|
|
}
|
|
}
|
|
|
|
BeatLevelRenderHelperImpl::~BeatLevelRenderHelperImpl() {}
|
|
|
|
std::unique_ptr<BeatLevelRenderHelper::LevelRenderIterator> BeatLevelRenderHelperImpl::getIterator(double time, float* matrix) const {
|
|
uint32_t timebegin = (time - jumpDuration/2);
|
|
uint32_t timeend = (time + jumpDuration/2);
|
|
|
|
if(timebegin > time) timebegin = 0;
|
|
if(timeend < time) timeend = std::numeric_limits<uint32_t>::max();
|
|
|
|
std::cout << "timebegin: " << timebegin << " timeend: " << timeend << std::endl;
|
|
|
|
return std::make_unique<LevelRenderIteratorImpl>(time, timebegin, timeend, notes, njs, bps, matrix);
|
|
}
|
|
|
|
BeatLevelRenderHelperImpl::LevelRenderIteratorImpl::LevelRenderIteratorImpl(double pos, uint32_t begin, uint32_t end, std::multimap<uint32_t, Note> notes, double njs, double bps, float* matrix) :
|
|
pos(pos), timebegin(begin), timeend(end), njs(njs), bps(bps), matrix(matrix) {
|
|
|
|
noteit = notes.lower_bound(begin);
|
|
noteitend = notes.upper_bound(end);
|
|
}
|
|
|
|
bool BeatLevelRenderHelperImpl::LevelRenderIteratorImpl::hasNextNote() const {
|
|
return noteit != noteitend;
|
|
}
|
|
|
|
const Note& BeatLevelRenderHelperImpl::LevelRenderIteratorImpl::getNextNote() {
|
|
const Note& note = (noteit++)->second;
|
|
setMat(pos, note);
|
|
return note;
|
|
}
|
|
|
|
const Wall& BeatLevelRenderHelperImpl::LevelRenderIteratorImpl::getNextWall() {
|
|
static const Wall EMPTY {};
|
|
return EMPTY;
|
|
}
|
|
|
|
|
|
//mat is a pointer to the matrix information in row first ordering
|
|
void BeatLevelRenderHelperImpl::LevelRenderIteratorImpl::setMat(double time, const Note& n) {
|
|
// double beat = bps * time;
|
|
|
|
//get matrix parameters
|
|
float offsetx = ((n.line - (LINECOUNT / 2.0)) * LINESPACING) + LINEOFFSET;
|
|
float offsety = (n.layer * LAYERSPACING) + LAYEROFFSET;
|
|
float offsetz = -((n.time) - time) * njs;
|
|
|
|
float rotationz = ROTLOOKUP[n.cutdir];
|
|
|
|
float cosrotz = cos(rotationz);
|
|
float sinrotz = sin(rotationz);
|
|
|
|
//build matrix
|
|
matrix[ 0] = cosrotz;
|
|
matrix[ 1] = -sinrotz;
|
|
matrix[ 2] = 0;
|
|
matrix[ 3] = offsetx;
|
|
|
|
matrix[ 4] = sinrotz;
|
|
matrix[ 5] = cosrotz;
|
|
matrix[ 6] = 0;
|
|
matrix[ 7] = offsety;
|
|
|
|
matrix[ 8] = 0;
|
|
matrix[ 9] = 0;
|
|
matrix[10] = 1;
|
|
matrix[11] = offsetz;
|
|
|
|
matrix[12] = 0;
|
|
matrix[13] = 0;
|
|
matrix[14] = 0;
|
|
matrix[15] = 1;
|
|
}
|
|
|
|
} |