diff --git a/include/beatsaber-impl/beatlevelrenderhelperimpl.h b/include/beatsaber-impl/beatlevelrenderhelperimpl.h index 6475259..7d57339 100644 --- a/include/beatsaber-impl/beatlevelrenderhelperimpl.h +++ b/include/beatsaber-impl/beatlevelrenderhelperimpl.h @@ -2,6 +2,8 @@ #include "beatlevelrenderhelper.h" +#include + namespace Beatsaber { class BeatLevelRenderHelperImpl : public BeatLevelRenderHelper { @@ -9,12 +11,44 @@ public: BeatLevelRenderHelperImpl(std::shared_ptr 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::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 notes, double njs, double bps, float* matrix); + + //friend class BeatLevelRenderHelperImpl; + }; + + virtual std::unique_ptr getIterator(double time, float* matrix) const override; private: std::shared_ptr level; + std::multimap 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 }; } \ No newline at end of file diff --git a/include/beatsaber/beatlevel.h b/include/beatsaber/beatlevel.h index 1d35e8b..44e1645 100644 --- a/include/beatsaber/beatlevel.h +++ b/include/beatsaber/beatlevel.h @@ -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; diff --git a/include/beatsaber/beatlevelrenderhelper.h b/include/beatsaber/beatlevelrenderhelper.h index 05400e5..22ba915 100644 --- a/include/beatsaber/beatlevelrenderhelper.h +++ b/include/beatsaber/beatlevelrenderhelper.h @@ -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 getIterator(double time, float* matrix) const = 0; }; } \ No newline at end of file diff --git a/src/beatlevelrenderhelper.cpp b/src/beatlevelrenderhelper.cpp index 1b253be..4d27c69 100644 --- a/src/beatlevelrenderhelper.cpp +++ b/src/beatlevelrenderhelper.cpp @@ -2,8 +2,11 @@ #include "beatmap.h" +#include //debug only + #include +// 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 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& originalNotes = level->getNotes(); + auto itHint = notes.begin(); + for(const Note& n : originalNotes) { + itHint = notes.insert(itHint, {n.time, n}); + } } BeatLevelRenderHelperImpl::~BeatLevelRenderHelperImpl() {} +std::unique_ptr 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::max(); + + std::cout << "timebegin: " << timebegin << " timeend: " << timeend << std::endl; + + return std::make_unique(time, timebegin, timeend, notes, njs, bps, matrix); +} + +BeatLevelRenderHelperImpl::LevelRenderIteratorImpl::LevelRenderIteratorImpl(double pos, uint32_t begin, uint32_t end, std::multimap 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; } } \ No newline at end of file