Original Post
Since I rewrote this function adding some functionality, I keep getting this debug error: "Run-time Check Failure #2 - Stack around the variable '$1' was corrupted." The strange thing is that there isn't a precise line that causes the error, rather it seems as if I run out of stack space because I'm using too many auto variables or something like that. I can say this because if I comment out one of the variables, or even make it static, I don't get the error. For example I can eliminate the FinalVelocity vector, and the problem disappears. But then if I create anywhere in the function (even outside loops) two or more float variables, the problem reappears, while it goes fine with just one float in this case. So it really seems that I'm reaching some stack limit, but look at the function, I don't think I'm doing nothing that should cause this. There are only two nested loops, and I'm getting this problem with only two entities in the game world. The function gets called once per frame. This is really driving me crazy. Do you have any idea of what I'm doing wrong?
void CEntityManager::UpdateEntities( float DeltaTime, IWorldModel* pWorld, CTerrain* pTerrain )
{
if( DeltaTime == 0.0f )
{
return;
}
// Check for "noclip" CVar
bool CheckCollisions = true;
if( g_pCVarMgr->CVarExists( "noclip" ) && ( g_pCVarMgr->GetBool( "noclip" ) == true ) )
{
CheckCollisions = false;
}
if( CheckCollisions )
{
//---------------------------------------------------------------------
//
// Pass 1: Gravity
//
//---------------------------------------------------------------------
for( Map_HandleToEntity::iterator itor = m_Entities.begin(); itor != m_Entities.end(); ++itor )
{
CEntity* pEnt = itor->second;
const D3DXVECTOR3& EntPos = pEnt->GetPosition();
// Check if will collide with the world
if( pWorld && pWorld->CheckGravityCollision( pEnt->GetPhysics(), DeltaTime ) )
{
pEnt->ResetGravity();
continue;
}
// Check if we will collide with another entity
bool Stopped = false;
for( Map_HandleToEntity::iterator j = itor; j != m_Entities.end(); ++j )
{
if( itor == j )
{
continue;
}
CEntity* pSecond = j->second;
if( pSecond->IsDead() )
{
continue;
}
if( math::SphereSphereCollide( pEnt->GetPhysics()->GetSphere(), pEnt->GetPhysics()->GetGravityVelocity() * DeltaTime,
pSecond->GetPhysics()->GetSphere(), pSecond->GetPhysics()->GetGravityVelocity() * DeltaTime ) )
{
pEnt->ResetGravity();
pSecond->ResetGravity();
Stopped = true;
break;
}
}
if( Stopped )
{
continue;
}
// Go down
pEnt->UpdateGravity( DeltaTime );
// Align with the terrain
if( pTerrain )
{
float Height = pTerrain->GetHeight( EntPos.x, EntPos.z ) + pEnt->GetPhysics()->GetSphere().GetRadius();
if( EntPos.y <= Height )
{
pEnt->SetPosition( D3DXVECTOR3( EntPos.x, Height, EntPos.z ) );
pEnt->ResetGravity();
}
}
}
//---------------------------------------------------------------------
//
// Pass 2: Velocity
//
//---------------------------------------------------------------------
// Check for collisions with the world
for( Map_HandleToEntity::iterator itor = m_Entities.begin(); itor != m_Entities.end(); ++itor )
{
CEntity* pEnt = itor->second;
if( pWorld )
{
pWorld->ResolveCollisions( pEnt->GetPhysics(), DeltaTime, WORLD_SLIDE );
}
// Set the new velocity modified by the terrain
D3DXVECTOR3 FinalPos = pEnt->GetPosition() + ( pEnt->GetPhysics()->GetVelocity() * DeltaTime );
float TerrainHeight = pTerrain->GetHeight( FinalPos.x, FinalPos.z ) + pEnt->GetPhysics()->GetSphere().GetRadius();
if( FinalPos.y <= TerrainHeight )
{
FinalPos.y = TerrainHeight;
}
D3DXVECTOR3 FinalVelocity = ( FinalPos - pEnt->GetPosition() );
D3DXVec3Normalize( &FinalVelocity, &FinalVelocity );
FinalVelocity *= D3DXVec3Length( &pEnt->GetPhysics()->GetVelocity() );
pEnt->GetPhysics()->SetVelocity( FinalVelocity );
}
// Check for collisions between entities
for( Map_HandleToEntity::iterator itor = m_Entities.begin(); itor != m_Entities.end(); ++itor )
{
CEntity* pFirst = itor->second;
if( pFirst->IsDead() )
{
continue;
}
for( Map_HandleToEntity::iterator j = itor; j != m_Entities.end(); ++j )
{
if( itor == j )
{
continue;
}
CEntity* pSecond = j->second;
if( pSecond->IsDead() )
{
continue;
}
pFirst->ResolveCollision( pSecond, DeltaTime );
}
}
}
// Finally update each entity
for( Map_HandleToEntity::iterator i = m_Entities.begin(); i != m_Entities.end(); ++i )
{
CEntity* e = i->second;
e->Update( DeltaTime );
}
}