libBeatsaber/src/beatlevelrenderhelper.cpp

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;
}
}