Performance optimizations: sound caching, renderer culling, entity and lighting improvements
- Sound engine: cache filesystem probe results to avoid repeated file existence checks; add MA_SOUND_FLAG_DECODE for pre-decoded playback - Level renderer: column-level frustum culling, compact visible chunk lists to skip empty iteration, lightweight second-pass render path, early-out for non-dirty chunks, scaled recheck period at high render distances - Entity: cache shared_from_this() to reduce reference counting overhead in move() and checkInsideTiles() - Level: skip checkLight() when tile light properties unchanged; enable entity locking on all platforms (not just Vita) - LevelChunk: only rescan min height when the minimum column changes; defer lightGap processing - LivingEntity: use raw pointer cast instead of dynamic_pointer_cast; cache friction tile lookup - ServerPlayerGameMode: return whether block was destroyed to avoid redundant tile update packets
This commit is contained in:
1 parent
80ba2e0762
commit
0ba923f085
12 files changed
+311
-170
No files matched your search
@@ -705,6 +705,8 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J -
|
||||
return;
|
||||
}
|
||||
|
||||
auto self = shared_from_this();
|
||||
|
||||
ySlideOffset *= 0.4f;
|
||||
|
||||
double xo = x;
|
||||
@@ -734,21 +736,21 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J -
|
||||
if (isPlayerSneaking)
|
||||
{
|
||||
double d = 0.05;
|
||||
while (xa != 0 && level->getCubes(shared_from_this(), bb->cloneMove(xa, -1.0, 0))->empty())
|
||||
while (xa != 0 && level->getCubes(self, bb->cloneMove(xa, -1.0, 0), true)->empty())
|
||||
{
|
||||
if (xa < d && xa >= -d) xa = 0;
|
||||
else if (xa > 0) xa -= d;
|
||||
else xa += d;
|
||||
xaOrg = xa;
|
||||
}
|
||||
while (za != 0 && level->getCubes(shared_from_this(), bb->cloneMove(0, -1.0, za))->empty())
|
||||
while (za != 0 && level->getCubes(self, bb->cloneMove(0, -1.0, za), true)->empty())
|
||||
{
|
||||
if (za < d && za >= -d) za = 0;
|
||||
else if (za > 0) za -= d;
|
||||
else za += d;
|
||||
zaOrg = za;
|
||||
}
|
||||
while (xa != 0 && za != 0 && level->getCubes(shared_from_this(), bb->cloneMove(xa, -1.0, za))->empty())
|
||||
while (xa != 0 && za != 0 && level->getCubes(self, bb->cloneMove(xa, -1.0, za), true)->empty())
|
||||
{
|
||||
if (xa < d && xa >= -d) xa = 0;
|
||||
else if (xa > 0) xa -= d;
|
||||
@@ -761,7 +763,7 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J -
|
||||
}
|
||||
}
|
||||
|
||||
AABBList *aABBs = level->getCubes(shared_from_this(), bb->expand(xa, ya, za), noEntityCubes, true);
|
||||
AABBList *aABBs = level->getCubes(self, bb->expand(xa, ya, za), noEntityCubes, true);
|
||||
|
||||
|
||||
// 4J Stu - Particles (and possibly other entities) don't have xChunk and zChunk set, so calculate the chunk instead
|
||||
@@ -816,7 +818,7 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J -
|
||||
bb->set(bbOrg);
|
||||
// 4J - added extra expand, as if we don't move up by footSize by hitting a block above us, then overall we could be trying to move as much as footSize downwards,
|
||||
// so we'd better include cubes under our feet in this list of things we might possibly collide with
|
||||
aABBs = level->getCubes(shared_from_this(), bb->expand(xa, ya, za)->expand(0,-ya,0),false,true);
|
||||
aABBs = level->getCubes(self, bb->expand(xa, ya, za)->expand(0,-ya,0),false,true);
|
||||
|
||||
if(!level->isClientSide || level->reallyHasChunk(xc, zc))
|
||||
{
|
||||
@@ -926,7 +928,7 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J -
|
||||
playSound(eSoundType_LIQUID_SWIM, speed, 1 + (random->nextFloat() - random->nextFloat()) * 0.4f);
|
||||
}
|
||||
playStepSound(xt, yt, zt, t);
|
||||
Tile::tiles[t]->stepOn(level, xt, yt, zt, shared_from_this());
|
||||
Tile::tiles[t]->stepOn(level, xt, yt, zt, self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,6 +971,7 @@ void Entity::checkInsideTiles()
|
||||
|
||||
if (level->hasChunksAt(x0, y0, z0, x1, y1, z1))
|
||||
{
|
||||
auto self = shared_from_this();
|
||||
for (int x = x0; x <= x1; x++)
|
||||
for (int y = y0; y <= y1; y++)
|
||||
for (int z = z0; z <= z1; z++)
|
||||
@@ -976,7 +979,7 @@ void Entity::checkInsideTiles()
|
||||
int t = level->getTile(x, y, z);
|
||||
if (t > 0)
|
||||
{
|
||||
Tile::tiles[t]->entityInside(level, x, y, z, shared_from_this());
|
||||
Tile::tiles[t]->entityInside(level, x, y, z, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -932,6 +932,7 @@ bool Level::setTileAndData(int x, int y, int z, int tile, int data, int updateFl
|
||||
int old = c->getTile(x & 15, y, z & 15);
|
||||
int olddata = c->getData( x & 15, y, z & 15);
|
||||
#endif
|
||||
int prevTile = c->getTile(x & 15, y, z & 15);
|
||||
result = c->setTileAndData(x & 15, y, z & 15, tile, data);
|
||||
if( updateFlags != Tile::UPDATE_INVISIBLE_NO_LIGHT)
|
||||
{
|
||||
@@ -939,7 +940,11 @@ bool Level::setTileAndData(int x, int y, int z, int tile, int data, int updateFl
|
||||
PIXBeginNamedEvent(0,"Checking light %d %d %d",x,y,z);
|
||||
PIXBeginNamedEvent(0,"was %d, %d now %d, %d",old,olddata,tile,data);
|
||||
#endif
|
||||
checkLight(x, y, z);
|
||||
if (Tile::lightBlock[tile & 0xff] != Tile::lightBlock[prevTile & 0xff] ||
|
||||
Tile::lightEmission[tile & 0xff] != Tile::lightEmission[prevTile & 0xff])
|
||||
{
|
||||
checkLight(x, y, z);
|
||||
}
|
||||
PIXEndNamedEvent();
|
||||
PIXEndNamedEvent();
|
||||
}
|
||||
@@ -3687,13 +3692,11 @@ vector<shared_ptr<Entity> > *Level::getEntities(shared_ptr<Entity> except, AABB
|
||||
int zc0 = Mth::floor((bb->z0 - 2) / 16);
|
||||
int zc1 = Mth::floor((bb->z1 + 2) / 16);
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#ifdef _ENTITIES_RW_SECTION
|
||||
// AP - RW critical sections are expensive so enter it here so we only have to call it once instead of X times
|
||||
EnterCriticalRWSection(&LevelChunk::m_csEntities, false);
|
||||
#else
|
||||
EnterCriticalSection(&LevelChunk::m_csEntities);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (int xc = xc0; xc <= xc1; xc++)
|
||||
@@ -3706,12 +3709,10 @@ vector<shared_ptr<Entity> > *Level::getEntities(shared_ptr<Entity> except, AABB
|
||||
}
|
||||
MemSect(0);
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#ifdef _ENTITIES_RW_SECTION
|
||||
LeaveCriticalRWSection(&LevelChunk::m_csEntities, false);
|
||||
#else
|
||||
LeaveCriticalSection(&LevelChunk::m_csEntities);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return &es;
|
||||
@@ -3730,13 +3731,11 @@ vector<shared_ptr<Entity> > *Level::getEntitiesOfClass(const type_info& baseClas
|
||||
int zc1 = Mth::floor((bb->z1 + 2) / 16);
|
||||
vector<shared_ptr<Entity> > *es = new vector<shared_ptr<Entity> >();
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#ifdef _ENTITIES_RW_SECTION
|
||||
// AP - RW critical sections are expensive so enter it here so we only have to call it once instead of X times
|
||||
EnterCriticalRWSection(&LevelChunk::m_csEntities, false);
|
||||
#else
|
||||
EnterCriticalSection(&LevelChunk::m_csEntities);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (int xc = xc0; xc <= xc1; xc++)
|
||||
@@ -3750,12 +3749,10 @@ vector<shared_ptr<Entity> > *Level::getEntitiesOfClass(const type_info& baseClas
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __PSVITA__
|
||||
#ifdef _ENTITIES_RW_SECTION
|
||||
LeaveCriticalRWSection(&LevelChunk::m_csEntities, false);
|
||||
#else
|
||||
LeaveCriticalSection(&LevelChunk::m_csEntities);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return es;
|
||||
|
||||
@@ -817,8 +817,9 @@ void LevelChunk::recalcHeight(int x, int yStart, int z)
|
||||
{
|
||||
minHeight = y;
|
||||
}
|
||||
else
|
||||
else if (yOld == minHeight)
|
||||
{
|
||||
// Only rescan when the column that was at the minimum changed height
|
||||
int min = Level::maxBuildHeight - 1;
|
||||
for (int _x = 0; _x < 16; _x++)
|
||||
for (int _z = 0; _z < 16; _z++)
|
||||
@@ -886,11 +887,16 @@ void LevelChunk::recalcHeight(int x, int yStart, int z)
|
||||
if (!level->dimension->hasCeiling)
|
||||
{
|
||||
PIXBeginNamedEvent(0,"Light gaps");
|
||||
lightGap(xOffs - 1, zOffs, y1, y2);
|
||||
lightGap(xOffs + 1, zOffs, y1, y2);
|
||||
lightGap(xOffs, zOffs - 1, y1, y2);
|
||||
lightGap(xOffs, zOffs + 1, y1, y2);
|
||||
lightGap(xOffs, zOffs, y1, y2);
|
||||
// Flag columns for gap rechecking — processed by recheckGaps() on next tick
|
||||
auto flagGap = [&](int wx, int wz) {
|
||||
LevelChunk *c = level->getChunkAt(wx, wz);
|
||||
if (c && !c->isEmpty()) c->lightGaps(wx & 15, wz & 15);
|
||||
};
|
||||
flagGap(xOffs - 1, zOffs);
|
||||
flagGap(xOffs + 1, zOffs);
|
||||
flagGap(xOffs, zOffs - 1);
|
||||
flagGap(xOffs, zOffs + 1);
|
||||
flagGap(xOffs, zOffs);
|
||||
PIXEndNamedEvent();
|
||||
}
|
||||
|
||||
@@ -1643,10 +1649,7 @@ void LevelChunk::getEntities(shared_ptr<Entity> except, AABB *bb, vector<shared_
|
||||
if (yc0 < 0) yc0 = 0;
|
||||
if (yc1 >= ENTITY_BLOCKS_LENGTH) yc1 = ENTITY_BLOCKS_LENGTH - 1;
|
||||
|
||||
#ifndef __PSVITA__
|
||||
// AP - RW critical sections are expensive so enter once in Level::getEntities
|
||||
EnterCriticalSection(&m_csEntities);
|
||||
#endif
|
||||
// Lock is now always held by Level::getEntities()
|
||||
for (int yc = yc0; yc <= yc1; yc++)
|
||||
{
|
||||
vector<shared_ptr<Entity> > *entities = entityBlocks[yc];
|
||||
@@ -1671,9 +1674,6 @@ void LevelChunk::getEntities(shared_ptr<Entity> except, AABB *bb, vector<shared_
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef __PSVITA__
|
||||
LeaveCriticalSection(&m_csEntities);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LevelChunk::getEntitiesOfClass(const type_info& ec, AABB *bb, vector<shared_ptr<Entity> > &es, const EntitySelector *selector)
|
||||
@@ -1698,10 +1698,7 @@ void LevelChunk::getEntitiesOfClass(const type_info& ec, AABB *bb, vector<shared
|
||||
yc1 = 0;
|
||||
}
|
||||
|
||||
#ifndef __PSVITA__
|
||||
// AP - RW critical sections are expensive so enter once in Level::getEntitiesOfClass
|
||||
EnterCriticalSection(&m_csEntities);
|
||||
#endif
|
||||
// Lock is now always held by Level::getEntitiesOfClass()
|
||||
for (int yc = yc0; yc <= yc1; yc++)
|
||||
{
|
||||
vector<shared_ptr<Entity> > *entities = entityBlocks[yc];
|
||||
@@ -1729,9 +1726,6 @@ void LevelChunk::getEntitiesOfClass(const type_info& ec, AABB *bb, vector<shared
|
||||
// 4J - note needs to be equivalent to baseClass.isAssignableFrom(e.getClass())
|
||||
}
|
||||
}
|
||||
#ifndef __PSVITA__
|
||||
LeaveCriticalSection(&m_csEntities);
|
||||
#endif
|
||||
}
|
||||
|
||||
int LevelChunk::countEntities()
|
||||
|
||||
@@ -1380,16 +1380,12 @@ void LivingEntity::jumpFromGround()
|
||||
|
||||
void LivingEntity::travel(float xa, float ya)
|
||||
{
|
||||
#ifdef __PSVITA__
|
||||
// AP - dynamic_pointer_cast is a non-trivial call
|
||||
// AP - dynamic_pointer_cast is a non-trivial call, use raw pointer instead
|
||||
Player *thisPlayer = nullptr;
|
||||
if( this->instanceof(eTYPE_PLAYER) )
|
||||
if (this->instanceof(eTYPE_PLAYER))
|
||||
{
|
||||
thisPlayer = (Player*) this;
|
||||
}
|
||||
#else
|
||||
shared_ptr<Player> thisPlayer = dynamic_pointer_cast<Player>(shared_from_this());
|
||||
#endif
|
||||
if (isInWater() && !(thisPlayer && thisPlayer->abilities.flying) )
|
||||
{
|
||||
double yo = y;
|
||||
@@ -1424,13 +1420,14 @@ void LivingEntity::travel(float xa, float ya)
|
||||
else
|
||||
{
|
||||
float friction = 0.91f;
|
||||
int frictionTile = 0;
|
||||
if (onGround)
|
||||
{
|
||||
frictionTile = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z));
|
||||
friction = 0.6f * 0.91f;
|
||||
int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z));
|
||||
if (t > 0)
|
||||
if (frictionTile > 0)
|
||||
{
|
||||
friction = Tile::tiles[t]->friction * 0.91f;
|
||||
friction = Tile::tiles[frictionTile]->friction * 0.91f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1452,10 +1449,9 @@ void LivingEntity::travel(float xa, float ya)
|
||||
if (onGround)
|
||||
{
|
||||
friction = 0.6f * 0.91f;
|
||||
int t = level->getTile( Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z));
|
||||
if (t > 0)
|
||||
if (frictionTile > 0)
|
||||
{
|
||||
friction = Tile::tiles[t]->friction * 0.91f;
|
||||
friction = Tile::tiles[frictionTile]->friction * 0.91f;
|
||||
}
|
||||
}
|
||||
if (onLadder())
|
||||
|
||||
Reference in new issue
Block a user