renderiterator

This commit is contained in:
mrbesen 2021-07-09 00:56:15 +02:00
parent 90f36901fd
commit be4098061b
Signed by: MrBesen
GPG Key ID: 596B2350DCD67504
4 changed files with 118 additions and 28 deletions

View File

@ -2,6 +2,8 @@
#include "beatlevelrenderhelper.h"
#include <map>
namespace Beatsaber {
class BeatLevelRenderHelperImpl : public BeatLevelRenderHelper {
@ -9,12 +11,44 @@ public:
BeatLevelRenderHelperImpl(std::shared_ptr<const BeatLevel> level);
virtual ~BeatLevelRenderHelperImpl();
//mat is a pointer to the matrix information in row first ordering
virtual void setMat(float* mat, double time, uint32_t note) override;
class LevelRenderIteratorImpl : public LevelRenderIterator {
public:
virtual bool hasNextNote() const override;
virtual const Note& getNextNote() override;
virtual const Wall& getNextWall() override;
private:
using noteIterator = std::multimap<uint32_t, Note>::const_iterator;
double pos;
uint32_t timebegin;
uint32_t timeend;
noteIterator noteit;
noteIterator noteitend;
double njs;
double bps;
float* matrix;
void setMat(double time, const Note& note);
public:
LevelRenderIteratorImpl(double pos, uint32_t begin, uint32_t end, std::multimap<uint32_t, Note> notes, double njs, double bps, float* matrix);
//friend class BeatLevelRenderHelperImpl;
};
virtual std::unique_ptr<BeatLevelRenderHelper::LevelRenderIterator> getIterator(double time, float* matrix) const override;
private:
std::shared_ptr<const BeatLevel> level;
std::multimap<uint32_t, Note> notes;
double bps; //beats per second
double njs; // note jump speed (in m/s)
double jumpDuration; // amount of seconds when a object is active
double jumpDistance; // distnce the objects travel within the jump duration
};
}

View File

@ -22,7 +22,7 @@ public:
virtual Difficulty::Difficulty getDifficulty() const = 0;
virtual int32_t getDifficultyRank() const = 0;
virtual std::string getFilename() const = 0;
virtual double getNoteJumpSpeed() const = 0; // in m
virtual double getNoteJumpSpeed() const = 0; // in m/s
virtual double getNoteStartOffset() const = 0;
virtual std::string getCustomData() const = 0;

View File

@ -10,8 +10,15 @@ public:
BeatLevelRenderHelper() {}
virtual ~BeatLevelRenderHelper() {}
//mat is a pointer to the matrix information in row first ordering
virtual void setMat(float* mat, double time, uint32_t note) = 0;
class LevelRenderIterator {
public:
virtual bool hasNextNote() const = 0;
virtual const Note& getNextNote() = 0;
virtual const Wall& getNextWall() = 0;
};
//get a iterator to all objects visible for a defined time period
virtual std::unique_ptr<BeatLevelRenderHelper::LevelRenderIterator> getIterator(double time, float* matrix) const = 0;
};
}

View File

@ -2,8 +2,11 @@
#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)
@ -18,6 +21,7 @@ static const float ROTLOOKUP[] {
namespace Beatsaber {
//TODO: make configureble
static const uint32_t LINECOUNT = 4;
static const uint32_t LAYERCOUNT = 3;
static const double LINESPACING = 0.6;
@ -25,24 +29,69 @@ 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::setMat(float* mat, double time, uint32_t note) {
if(!mat) return;
double beat = bps * time;
const Note& n = level->getNotes().at(note);
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 - beat);
float offsetz = -((n.time) - time) * njs;
float rotationz = ROTLOOKUP[n.cutdir];
@ -50,25 +99,25 @@ void BeatLevelRenderHelperImpl::setMat(float* mat, double time, uint32_t note) {
float sinrotz = sin(rotationz);
//build matrix
mat[ 0] = cosrotz;
mat[ 1] = -sinrotz;
mat[ 2] = 0;
mat[ 3] = offsetx;
matrix[ 0] = cosrotz;
matrix[ 1] = -sinrotz;
matrix[ 2] = 0;
matrix[ 3] = offsetx;
mat[ 4] = sinrotz;
mat[ 5] = cosrotz;
mat[ 6] = 0;
mat[ 7] = offsety;
matrix[ 4] = sinrotz;
matrix[ 5] = cosrotz;
matrix[ 6] = 0;
matrix[ 7] = offsety;
mat[ 8] = 0;
mat[ 9] = 0;
mat[10] = 1;
mat[11] = offsetz;
matrix[ 8] = 0;
matrix[ 9] = 0;
matrix[10] = 1;
matrix[11] = offsetz;
mat[12] = 0;
mat[13] = 0;
mat[14] = 0;
mat[15] = 1;
matrix[12] = 0;
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;
}
}