From 16ae453431a87c233d9d0574181ef305771cab25 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Mon, 2 Jan 2012 16:02:32 +0100 Subject: [PATCH] Revert "Fix some small performance bottlenecks:" This reverts commit 2d7eeb47811fdff36b478829acbeda90581eb2da. --- Aquaria/Avatar.cpp | 3 +- Aquaria/CollideEntity.cpp | 7 +- Aquaria/Game.cpp | 78 ++++++---------- Aquaria/Game.h | 15 +-- Aquaria/GridRender.cpp | 95 +++++++++---------- Aquaria/Segmented.cpp | 39 ++++++-- Aquaria/TileVector.h | 11 +-- BBGE/OpenGLStubs.h | 1 - BBGE/RenderObject.cpp | 33 ++++++- BBGE/RenderObject.h | 2 +- BBGE/Vector.cpp | 192 +++++++++++++++++++++++++++++++------- BBGE/Vector.h | 52 ++++++++--- 12 files changed, 345 insertions(+), 183 deletions(-) diff --git a/Aquaria/Avatar.cpp b/Aquaria/Avatar.cpp index 8bc293e..f7da9b4 100644 --- a/Aquaria/Avatar.cpp +++ b/Aquaria/Avatar.cpp @@ -9092,8 +9092,9 @@ void Avatar::onUpdate(float dt) int hw = collideCircle; + Vector fix; - if (dsq->game->collideCircleWithGrid(position, hw)) + if (dsq->game->collideCircleWithGrid(position, hw, &fix)) { if (dsq->game->lastCollideTileType == OT_HURT && dsq->continuity.getWorldType() != WT_SPIRIT diff --git a/Aquaria/CollideEntity.cpp b/Aquaria/CollideEntity.cpp index c35aba6..1d73e65 100644 --- a/Aquaria/CollideEntity.cpp +++ b/Aquaria/CollideEntity.cpp @@ -206,6 +206,7 @@ void CollideEntity::updateMovement(float dt) const int hw = collideRadius; bool freeRange = false; + Vector fix; if (isv(EV_COLLIDELEVEL,1)) { @@ -215,7 +216,7 @@ void CollideEntity::updateMovement(float dt) bool doesFreeRange = !isPullable(); if (doesFreeRange) { - if (dsq->game->collideCircleWithGrid(position, hw)) + if (dsq->game->collideCircleWithGrid(position, hw, &fix)) { // starting in a collision state freeRange = true; @@ -231,7 +232,7 @@ void CollideEntity::updateMovement(float dt) { if (getState() == STATE_PUSH) { - if (!freeRange && dsq->game->collideCircleWithGrid(position, hw)) + if (!freeRange && dsq->game->collideCircleWithGrid(position, hw, &fix)) { position = lastPosition; collided = true; @@ -240,7 +241,7 @@ void CollideEntity::updateMovement(float dt) } else { - if (!freeRange && ((!canLeaveWater && !isUnderWater() && wasUnderWater) || dsq->game->collideCircleWithGrid(position, hw))) + if (!freeRange && ((!canLeaveWater && !isUnderWater() && wasUnderWater) || dsq->game->collideCircleWithGrid(position, hw, &fix))) { position = lastPosition; onHitWall(); diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 32707d8..d9c4fa9 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -11161,72 +11161,47 @@ Vector Game::getClosestPointOnLine(Vector a, Vector b, Vector p) return a + V; } -bool Game::collideCircleWithGrid(const Vector& position, int r) +bool Game::collideCircleWithGrid(Vector position, int r, Vector *fill) { - TileVector t(position); + Vector tile = position; + TileVector t(tile); + tile.x = t.x; + tile.y = t.y; - const float hsz = TILE_SIZE/2; - const int xrange = (r/TILE_SIZE)+1; - const int yrange = (r/TILE_SIZE)+1; + float hsz = TILE_SIZE/2; + int xrange=1,yrange=1; + xrange = (r/TILE_SIZE)+1; + yrange = (r/TILE_SIZE)+1; - // quick early check if out of bounds - const int xstart = t.x-xrange; - const int ystart = t.y-yrange; - if (xstart < 0 || ystart < 0) + for (int x = tile.x-xrange; x <= tile.x+xrange; x++) { - lastCollideTileType = (ObsType)1; - lastCollidePosition = TileVector::worldVector(xstart, ystart); - return true; - } - - const int r2 = sqr(r); - const int xmax = t.x+xrange; - const int ymax = t.y+yrange; - - for (int x = xstart; x <= xmax; x++) - { - if (x >= MAX_GRID) + for (int y = tile.y-yrange; y <= tile.y+yrange; y++) { - lastCollideTileType = (ObsType)1; - lastCollidePosition = TileVector::worldVector(x, ystart); - return true; - } - - for (int y = ystart; y <= ymax; y++) - { - if (y >= MAX_GRID) - { - lastCollideTileType = (ObsType)1; - lastCollidePosition = TileVector::worldVector(x, y); - return true; - } - - int v = getGridRaw(x, y); // known to be in bounds + int v = this->getGrid(TileVector(x, y)); if (v != 0) { - lastCollidePosition = TileVector::worldVector(x, y); + //if (tile.x == x && tile.y == y) return true; + TileVector t(x, y); + lastCollidePosition = t.worldVector(); + //if (tile.x == x && tile.y == y) return true; float rx = (x*TILE_SIZE)+TILE_SIZE/2; float ry = (y*TILE_SIZE)+TILE_SIZE/2; + float rSqr; lastCollideTileType = (ObsType)v; - float yp = sqr(position.y - (ry+hsz)); - float xp = sqr(position.x - (rx+hsz)); + rSqr = sqr(position.x - (rx+hsz)) + sqr(position.y - (ry+hsz)); + if (rSqr < sqr(r)) return true; - if (xp + yp < r2) - return true; + rSqr = sqr(position.x - (rx-hsz)) + sqr(position.y - (ry+hsz)); + if (rSqr < sqr(r)) return true; - float xm = sqr(position.x - (rx-hsz)); + rSqr = sqr(position.x - (rx-hsz)) + sqr(position.y - (ry-hsz)); + if (rSqr < sqr(r)) return true; - if (xm + yp < r2) - return true; + rSqr = sqr(position.x - (rx+hsz)) + sqr(position.y - (ry-hsz)); + if (rSqr < sqr(r)) return true; - float ym = sqr(position.y - (ry-hsz)); - if (xm + ym < r2) - return true; - - if (xp < ym) - return true; if (position.x > rx-hsz && position.x < rx+hsz) { @@ -11236,6 +11211,7 @@ bool Game::collideCircleWithGrid(const Vector& position, int r) } } + if (position.y > ry-hsz && position.y < ry+hsz) { if (fabsf(rx - position.x) < r+hsz) @@ -11250,7 +11226,7 @@ bool Game::collideCircleWithGrid(const Vector& position, int r) return false; } -bool Game::collideBoxWithGrid(const Vector& position, int hw, int hh) +bool Game::collideBoxWithGrid(Vector position, int hw, int hh) { Vector tile = position; TileVector t(tile); diff --git a/Aquaria/Game.h b/Aquaria/Game.h index 61652f3..7c4b156 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -636,8 +636,7 @@ public: std::string getSelectedChoice() { return selectedChoice; } - int getGrid(const TileVector &tile) const; - int getGridRaw(unsigned int x, unsigned int y) const; + int getGrid(const TileVector &tile); const signed char *getGridColumn(int tileX); void setGrid(const TileVector &tile, int v); bool isObstructed(const TileVector &tile, int t = -1); @@ -670,8 +669,8 @@ public: void registerSporeDrop(const Vector &pos, int t); - bool collideBoxWithGrid(const Vector& position, int w, int h); - bool collideCircleWithGrid(const Vector& position, int r); + bool collideBoxWithGrid(Vector position, int w, int h); + bool collideCircleWithGrid(Vector position, int r, Vector *fill=0); bool collideHairVsCircle(Entity *a, int num, const Vector &pos2, int radius, float perc=0); @@ -1215,13 +1214,7 @@ extern Game *game; // INLINE FUNCTIONS inline -int Game::getGridRaw(unsigned int x, unsigned int y) const -{ - return grid[x][y]; -} - -inline -int Game::getGrid(const TileVector &tile) const +int Game::getGrid(const TileVector &tile) { if (tile.x < 0 || tile.x >= MAX_GRID || tile.y < 0 || tile.y >= MAX_GRID) return 1; return grid[tile.x][tile.y]; diff --git a/Aquaria/GridRender.cpp b/Aquaria/GridRender.cpp index 3d16660..a22465e 100644 --- a/Aquaria/GridRender.cpp +++ b/Aquaria/GridRender.cpp @@ -39,31 +39,6 @@ void GridRender::onUpdate(float dt) if (obsType != OT_BLACK) { blendEnabled = true; } } -inline static void doRenderGrid(int x, int startCol, int endCol) -{ - const int drawx1 = x*TILE_SIZE; - const int drawx2 = (x+1)*TILE_SIZE; - const int drawy1 = startCol*TILE_SIZE; - const int drawy2 = (endCol+1)*TILE_SIZE; - -#ifdef BBGE_BUILD_OPENGL - glBegin(GL_QUADS); - glVertex3i(drawx1, drawy2, 0.0f); - glVertex3i(drawx2, drawy2, 0.0f); - glVertex3i(drawx2, drawy1, 0.0f); - glVertex3i(drawx1, drawy1, 0.0f); - glEnd(); -#endif - -#ifdef BBGE_BUILD_DIRECTX - core->blitD3DVerts(0, - drawx1, drawy1, - drawx2, drawy1, - drawx2, drawy2, - drawx1, drawy2); -#endif -} - void GridRender::onRender() { switch(obsType) @@ -84,7 +59,7 @@ void GridRender::onRender() break; } - int obsType = this->obsType; + const int obsType = int(this->obsType); Vector camPos = core->cameraPos; camPos.x -= core->getVirtualOffX() * (core->invGlobalScale); const TileVector ct(camPos); @@ -102,43 +77,57 @@ void GridRender::onRender() startY = 0; if (endY >= MAX_GRID) endY = MAX_GRID-1; - for (int x = startX; x <= endX; ++x) + for (int x = startX; x <= endX; x++) { const signed char *gridColumn = dsq->game->getGridColumn(x); - int startCol = -1, y; - - // fast-forward to next drawable byte - if(const signed char *next = (const signed char*)memchr(gridColumn + startY, obsType, endY - startY + 1)) // find next byte with correct obs type + int startCol = -1, endCol; + for (int y = startY; y <= endY; y++) { - y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol - startCol = y; - } - else - continue; // nothing do draw in this column + int v = gridColumn[y]; + // HACK: Don't draw the leftmost or rightmost column of + // black tiles (otherwise they "leak out" around the + // edges of the Sun Temple). --achurch + if (v == OT_BLACK && ((dsq->game->getGridColumn(x-1))[y] != OT_BLACK || (dsq->game->getGridColumn(x+1))[y] != OT_BLACK)) + v = OT_EMPTY; - for ( ; y < endY; ++y) - { - if (gridColumn[y] != obsType) + if (v == obsType && startCol == -1) { - doRenderGrid(x, startCol, y - 1); - - // fast-forward to next drawable byte - if(const signed char *next = (const signed char*)memchr(gridColumn + y, obsType, endY - y)) // find next byte with correct obs type - { - y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol - startCol = y; - } - else - break; + startCol = y; + } + else if ((v != obsType || y == endY) && startCol != -1) + { + endCol = y; + if (v != obsType) + endCol--; + + const float drawx1 = x*TILE_SIZE; + const float drawx2 = (x+1)*TILE_SIZE; + const float drawy1 = startCol*TILE_SIZE; + const float drawy2 = (endCol+1)*TILE_SIZE; + +#ifdef BBGE_BUILD_OPENGL + glBegin(GL_QUADS); + glVertex3f(drawx1, drawy2, 0.0f); + glVertex3f(drawx2, drawy2, 0.0f); + glVertex3f(drawx2, drawy1, 0.0f); + glVertex3f(drawx1, drawy1, 0.0f); + glEnd(); +#endif + +#ifdef BBGE_BUILD_DIRECTX + core->blitD3DVerts(0, + drawx1, drawy1, + drawx2, drawy1, + drawx2, drawy2, + drawx1, drawy2); +#endif + startCol = -1; } - } - if (y == endY) - { - doRenderGrid(x, startCol, y); } } } + SongLineRender::SongLineRender() { followCamera = 1; diff --git a/Aquaria/Segmented.cpp b/Aquaria/Segmented.cpp index b09d06b..ecf1e7e 100644 --- a/Aquaria/Segmented.cpp +++ b/Aquaria/Segmented.cpp @@ -46,7 +46,11 @@ void Segmented::destroySegments(float life) for (int i = 0; i < segments.size(); i++) { segments[i]->setLife(life); - segments[i]->setDecayRate(1.0f); + segments[i]->setDecayRate(1.0); + + //segments[i]->setLife(1.0); + //segments[i]->setDecayRate(1.0/life); + //segments[i]->setDecayRate(1.0/life); segments[i]->fadeAlphaWithLife = true; } segments.clear(); @@ -80,7 +84,7 @@ void Segmented::updateSegment(int i, const Vector &diff) float angle; MathFunctions::calculateAngleBetweenVectorsInDegrees(Vector(0,0,0), diff, angle); - segments[i]->rotation.interpolateTo(Vector(0,0,angle), 0.2f); + segments[i]->rotation.interpolateTo(Vector(0,0,angle), 0.2); } void Segmented::updateAlpha(float a) @@ -101,25 +105,46 @@ void Segmented::warpSegments(const Vector &position) void Segmented::updateSegments(const Vector &position, bool reverse) { + /* + if (lastPositions.empty()) + { + for (int i = 0; i < segments.size(); i++) + { + segments[i]->position = position; + } + lastPositions.resize(numSegments); + for (int i = 0; i < numSegments; i++) + { + lastPositions.push_back(position); + } + } + */ const int top = segments.size()-1; - const Vector *lastPosition = &position; + Vector lastPosition = position; if (!reverse) { for (int i = 0; i <= top; i++) { - const Vector diff = *lastPosition - segments[i]->position; + const Vector diff = lastPosition - segments[i]->position; updateSegment(i, diff); - lastPosition = &segments[i]->position; + lastPosition = segments[i]->position; } } else { for (int i = top; i >= 0; i--) { - const Vector diff = *lastPosition - segments[i]->position; + const Vector diff = lastPosition - segments[i]->position; updateSegment(i, diff); - lastPosition = &segments[i]->position; + lastPosition = segments[i]->position; } } + /* + for (int i = lastPositions.size()-1; i > 0; i--) + { + lastPositions[i] = lastPositions[i-1]; + } + lastPositions[0] = position; + */ } diff --git a/Aquaria/TileVector.h b/Aquaria/TileVector.h index b3620f0..d274271 100644 --- a/Aquaria/TileVector.h +++ b/Aquaria/TileVector.h @@ -37,19 +37,14 @@ public: TileVector() : x(0),y(0) {} - inline Vector worldVector() const - { - return worldVector(x, y); - } - - inline static Vector worldVector(int x, int y) + Vector worldVector() const { return Vector(x*TILE_SIZE+TILE_SIZE/2, y*TILE_SIZE+TILE_SIZE/2); } - inline bool isZero() const + bool isZero() const { - return !(x | y); + return (x==0 && y==0); } int x,y; diff --git a/BBGE/OpenGLStubs.h b/BBGE/OpenGLStubs.h index 70f39ed..289b206 100644 --- a/BBGE/OpenGLStubs.h +++ b/BBGE/OpenGLStubs.h @@ -94,7 +94,6 @@ GL_FUNC(void,glTexCoord2f,(GLfloat s, GLfloat t),(s,t),) GL_FUNC(void,glTexCoord2d,(GLdouble s, GLdouble t),(s,t),) GL_FUNC(void,glVertex2f,(GLfloat x, GLfloat y),(x,y),) GL_FUNC(void,glVertex3f,(GLfloat x, GLfloat y, GLfloat z),(x,y,z),) -GL_FUNC(void,glVertex3i,(GLint x, GLint y, GLint z),(x,y,z),) // stuff GLU needs... GL_FUNC(void,glGetIntegerv,(GLenum pname, GLint *params),(pname,params),) diff --git a/BBGE/RenderObject.cpp b/BBGE/RenderObject.cpp index 8ff255c..f29e2ef 100644 --- a/BBGE/RenderObject.cpp +++ b/BBGE/RenderObject.cpp @@ -297,7 +297,7 @@ Vector RenderObject::getInvRotPosition(const Vector &vec) } void RenderObject::matrixChain() -{ +{ if (parent) parent->matrixChain(); @@ -1256,8 +1256,35 @@ void RenderObject::onUpdate(float dt) // left that above for safety since I'm not certain. --achurch if (isHidden()) return; - position += velocity * dt; - velocity += gravity * dt; + /* + width.update(dt); + height.update(dt); + */ + + + /* + if (!parent && !children.empty() && shareAlphaWithChildren) + { + propogateAlpha(); + } + */ + + + /* + if (flipTimer.updateCheck(dt)) + { + if (flipState == 0) + { + _fh = !_fh; + flipState = 1; + } + } + */ + + if (!velocity.isZero()) + position += velocity * dt; + if (!gravity.isZero()) + velocity += gravity * dt; position.update(dt); velocity.update(dt); scale.update(dt); diff --git a/BBGE/RenderObject.h b/BBGE/RenderObject.h index 5756252..fa8a000 100644 --- a/BBGE/RenderObject.h +++ b/BBGE/RenderObject.h @@ -221,7 +221,7 @@ public: inline Vector getFollowCameraPosition() const; void lookAt(const Vector &pos, float t, float minAngle, float maxAngle, float offset=0); - inline RenderObject *getParent() const {return parent;} + RenderObject *getParent() const {return parent;} void applyBlendType(); void fhTo(bool fh); void addDeathNotify(RenderObject *r); diff --git a/BBGE/Vector.cpp b/BBGE/Vector.cpp index 13008d5..811d4f0 100644 --- a/BBGE/Vector.cpp +++ b/BBGE/Vector.cpp @@ -268,6 +268,19 @@ void VectorPath::append(const VectorPath &path) pathNodes.push_back(path.pathNodes[i]); } +void VectorPath::subdivide() +{ + /* + std::vector copy = pathNodes; + pathNodes.clear(); + for (int i = 0; i < copy.size(); i++) + { + if (i < 4) + pathNodes.push_back(i); + } + */ +} + void VectorPath::cut(int n) { std::vector copy = pathNodes; @@ -289,7 +302,7 @@ void VectorPath::removeNode(int t) } } -Vector VectorPath::getValue(float usePercent) +Vector VectorPath::getValue(float percent) { if (pathNodes.empty()) { @@ -297,9 +310,11 @@ Vector VectorPath::getValue(float usePercent) return Vector(0,0,0); } - VectorPathNode *target = 0; - VectorPathNode *from = &pathNodes[0]; - for (int i = 0; i < pathNodes.size(); ++i) + float usePercent = percent; + VectorPathNode *from = 0, *target = 0; + from = &pathNodes[0]; + int i = 0; + for (i = 0; i < pathNodes.size(); i++) { if (pathNodes[i].percent >= usePercent) { @@ -445,11 +460,28 @@ float InterpolatedVector::interpolateTo(Vector vec, float timePeriod, int loopTy data->loopType = loopType; data->pingPong = pingPong; - data->interpolating = true; + + if (!data->trigger) + { + if (flag != IS_LOOPING) + { + data->startOfInterpolationEvent.call(); + data->endOfInterpolationEvent.set(0); + } + data->interpolating = true; + } + else + data->pendingInterpolation = true; return data->timePeriod; } +void InterpolatedVector::setInterpolationTrigger(InterpolatedVector *trigger, bool triggerFlag) +{ + InterpolatedVectorData *data = ensureData(); + data->trigger = trigger; + data->triggerFlag = triggerFlag; +} void InterpolatedVector::stop() { if (data) @@ -466,8 +498,34 @@ void InterpolatedVector::startPath(float time, float ease) data->followingPath = true; data->loopType = 0; data->pingPong = false; + data->speedPath = false; + data->endOfPathEvent.set(0); // get the right values to start off with updatePath(0); + data->timeSpeedEase = ease; + if (ease > 0) + { + data->timeSpeedMultiplier = 0; + } + else + { + data->timeSpeedMultiplier = 1; + } +} + +void InterpolatedVector::startSpeedPath(float speed) +{ + InterpolatedVectorData *data = ensureData(); + + data->ease = false; + data->currentPathNode = 0; + data->pathTimer = 0; + data->pathSpeed = speed; + data->followingPath = true; + data->loopType = 0; + data->pingPong = false; + data->speedPath = true; + updatePath(0); } void InterpolatedVector::stopPath() @@ -485,46 +543,109 @@ void InterpolatedVector::resumePath() void InterpolatedVector::updatePath(float dt) { InterpolatedVectorData *data = ensureData(); - if (data->pathTimer > data->pathTime) + + if (!data->speedPath) { - Vector value = data->path.getPathNode(data->path.getNumPathNodes()-1)->value; - this->x = value.x; - this->y = value.y; - this->z = value.z; - if (data->loopType != 0) + if (data->pathTimer > data->pathTime) { - if (data->loopType > 0) - data->loopType -= 1; - - int oldLoopType = data->loopType; - - if (data->pingPong) + Vector value = data->path.getPathNode(data->path.getNumPathNodes()-1)->value; + this->x = value.x; + this->y = value.y; + this->z = value.z; + if (data->loopType != 0) { - // flip path - data->path.flip(); - startPath(data->pathTime); - data->loopType = oldLoopType; + if (data->loopType > 0) + data->loopType -= 1; + + int oldLoopType = data->loopType; + + if (data->pingPong) + { + // flip path + data->path.flip(); + startPath(data->pathTime); + data->loopType = oldLoopType; + } + else + { + startPath(data->pathTime); + data->loopType = oldLoopType; + } } else { - startPath(data->pathTime); - data->loopType = oldLoopType; + stopPath(); + data->endOfPathEvent.call(); } } else { - stopPath(); + data->pathTimer += dt * data->pathTimeMultiplier; + + // ;//dt*data->timeSpeedMultiplier; + float perc = data->pathTimer/data->pathTime; + Vector value = data->path.getValue(perc); + this->x = value.x; + this->y = value.y; + this->z = value.z; + + + + /* + std::ostringstream os; + os << "nodes: " << data->path.getNumPathNodes() << " pathTimer: " << data->pathTimer << " pathTime: " << data->pathTime << " perc: " << perc << " p(" << x << ", " << y << ")"; + debugLog(os.str()); + */ + /* + float diff = data->pathTime - data->pathTimer; + if (data->timeSpeedEase > 0) + { + float secs = 1.0f/data->timeSpeedEase; + if (diff <= secs) + { + data->timeSpeedMultiplier -= dt*data->timeSpeedEase; + if (data->timeSpeedMultiplier < 0.1f) + data->timeSpeedMultiplier = 0.1f; + } + } + if (data->timeSpeedMultiplier < 1) + { + data->timeSpeedMultiplier += dt*data->timeSpeedEase; + if (data->timeSpeedMultiplier >= 1) + data->timeSpeedMultiplier = 1; + } + */ + } } else { - data->pathTimer += dt * data->pathTimeMultiplier; - - float perc = data->pathTimer/data->pathTime; - Vector value = data->path.getValue(perc); - this->x = value.x; - this->y = value.y; - this->z = value.z; + if (!isInterpolating()) + { + data->currentPathNode++; + VectorPathNode *node = data->path.getPathNode(data->currentPathNode); + /* + if (node) + { + + } + else + { + stopPath(); + data->endOfPathEvent.call(); + } + */ + if (node) + { + interpolateTo(node->value, (node->value - Vector(this->x, this->y, this->z)).getLength3D()*(1.0f/data->pathSpeed)); + } + else + { + // handle looping etc + stopPath(); + data->endOfPathEvent.call(); + } + } } } @@ -553,9 +674,9 @@ void InterpolatedVector::doInterpolate(float dt) } */ data->timePassed += dt; - if (data->timePassed >= data->timePeriod) + if (data->timePassed >= data->timePeriod) { - this->x = data->target.x; + this->x = data->target.x; this->y = data->target.y; this->z = data->target.z; data->interpolating = false; @@ -577,6 +698,11 @@ void InterpolatedVector::doInterpolate(float dt) interpolateTo (data->target, data->timePeriod, data->loopType, data->pingPong, data->ease, IS_LOOPING); } } + else + { + data->endOfInterpolationEvent.call(); + data->endOfInterpolationEvent.set(0); + } } else diff --git a/BBGE/Vector.h b/BBGE/Vector.h index 798cded..1f4ca3a 100644 --- a/BBGE/Vector.h +++ b/BBGE/Vector.h @@ -435,6 +435,7 @@ public: void realPercentageCalc(); void removeNodes(int startInclusive, int endInclusive); float getSubSectionLength(int startIncl, int endIncl); + void subdivide(); protected: std::vector pathNodes; }; @@ -445,34 +446,52 @@ struct InterpolatedVectorData { InterpolatedVectorData() { + trigger = 0; + triggerFlag = false; + pendingInterpolation = false; interpolating = false; pingPong = false; loopType = 0; pathTimer = 0; pathTime = 0; pathSpeed = 1; + currentPathNode = 0; pathTimeMultiplier = 1; timePassed = 0; timePeriod = 0; + timeSpeedMultiplier = 1; + timeSpeedEase = 0; //fakeTimePassed = 0; + speedPath = false; ease = false; followingPath = false; } - Vector from; - Vector target; - - VectorPath path; - - int loopType; - - float pathTimer, pathTime; - float pathSpeed; - float pathTimeMultiplier; - float timePassed, timePeriod; + InterpolatedVector *trigger; + bool triggerFlag; + bool pendingInterpolation; bool interpolating; bool pingPong; + int loopType; + + EventPtr endOfInterpolationEvent; + EventPtr startOfInterpolationEvent; + EventPtr endOfPathEvent; + + VectorPath path; + float pathTimer, pathTime; + float pathSpeed; + int currentPathNode; + float pathTimeMultiplier; + + float timePassed, timePeriod; + Vector target; + Vector from; + + float timeSpeedMultiplier, timeSpeedEase; + //float fakeTimePassed; + bool speedPath; bool ease; bool followingPath; }; @@ -511,6 +530,7 @@ public: return *this; } + void setInterpolationTrigger(InterpolatedVector *trigger, bool triggerFlag); enum InterpolateToFlag { NONE=0, IS_LOOPING }; float interpolateTo (Vector vec, float timePeriod, int loopType = 0, bool pingPong = false, bool ease = false, InterpolateToFlag flag = NONE); void inline update(float dt) @@ -518,6 +538,16 @@ public: if (!data) return; + if (data->pendingInterpolation && data->trigger) + { + if (data->trigger->isInterpolating() == data->triggerFlag) + { + data->interpolating = true; + data->pendingInterpolation = false; + } + else + return; + } if (isFollowingPath()) { updatePath(dt);