1
  • EDIT - The code looks strange here, so I suggest viewing the files directly in the link given.

While working on my engine, I came across a issue that I'm unable to resolve. Hoping to fix this without any heavy modification, the code is below.

void Block::DoCollision(GameObject* obj){
 obj->DoCollision(this);
}

That is where the stack overflow occurs. This application works perfectly fine until I create two instances of the class using the new keyword. If I only had 1 instance of the class, it worked fine.

Block* a = new Block(0, 0, 0, 5);
AddGameObject(a);
a = new Block(30, 0, 0, 5);
AddGameObject(a);

Those parameters are just x,y,z and size.

The code is checked before hand. Only a object with a matching Collisonflag and collision type will trigger the DoCollision(); function.

((*list1)->m_collisionFlag & (*list2)->m_type)

Maybe my check is messed up though. I attached the files concerned here http://celestialcoding.com/index.php?topic=1465.msg9913;topicseen#new. You can download them without having to sign up. The main suspects, I also pasted the code for below.

From GameManager.cpp

void GameManager::Update(float dt){
 GameList::iterator list1;

 for(list1=m_gameObjectList.begin(); list1 != m_gameObjectList.end(); ++list1){
  GameObject* temp = *list1;

  // Update logic and positions
  if((*list1)->m_active){
   (*list1)->Update(dt);
 //  Clip((*list1)->m_position); // Modify for bounce affect
  } else continue;

  // Check for collisions
  if((*list1)->m_collisionFlag != GameObject::TYPE_NONE){
   GameList::iterator list2;
   for(list2=m_gameObjectList.begin(); list2 != m_gameObjectList.end(); ++list2){
    if(!(*list2)->m_active)
     continue;
    if(list1 == list2)
     continue;
    if( (*list2)->m_active && 
     ((*list1)->m_collisionFlag & (*list2)->m_type) && 
     (*list1)->IsColliding(*list2)){
      (*list1)->DoCollision((*list2));
    }
   }
  }
  if(list1==m_gameObjectList.end()) break;
 }
 GameList::iterator end    = m_gameObjectList.end();
 GameList::iterator newEnd = remove_if(m_gameObjectList.begin(),m_gameObjectList.end(),RemoveNotActive);
 if(newEnd != end)
        m_gameObjectList.erase(newEnd,end);
}

void GameManager::LoadAllFiles(){
 LoadSkin(m_gameTextureList, "Models/Skybox/Images/Top.bmp",   GetNextFreeID());
 LoadSkin(m_gameTextureList, "Models/Skybox/Images/Right.bmp",  GetNextFreeID());
 LoadSkin(m_gameTextureList, "Models/Skybox/Images/Back.bmp",  GetNextFreeID());
 LoadSkin(m_gameTextureList, "Models/Skybox/Images/Left.bmp",  GetNextFreeID());
 LoadSkin(m_gameTextureList, "Models/Skybox/Images/Front.bmp",  GetNextFreeID());
 LoadSkin(m_gameTextureList, "Models/Skybox/Images/Bottom.bmp",  GetNextFreeID());
 LoadSkin(m_gameTextureList, "Terrain/Textures/Terrain1.bmp",  GetNextFreeID());
 LoadSkin(m_gameTextureList, "Terrain/Textures/Terrain2.bmp",  GetNextFreeID());
 LoadSkin(m_gameTextureList, "Terrain/Details/TerrainDetails.bmp", GetNextFreeID());
 LoadSkin(m_gameTextureList, "Terrain/Textures/Water1.bmp",   GetNextFreeID());




 Block* a = new Block(0, 0, 0, 5);
 AddGameObject(a);
 a = new Block(30, 0, 0, 5);
 AddGameObject(a);
 Player* d = new Player(0, 100,0);
 AddGameObject(d);
}



void Block::Draw(){

 glPushMatrix();
  glTranslatef(m_position.x(), m_position.y(), m_position.z());
  glRotatef(m_facingAngle, 0, 1, 0);
  glScalef(m_size, m_size, m_size);
  glBegin(GL_LINES);
   glColor3f(255, 255, 255);
   glVertex3f(m_boundingRect.left, m_boundingRect.top, m_position.z());
   glVertex3f(m_boundingRect.right, m_boundingRect.top, m_position.z());
   glVertex3f(m_boundingRect.left, m_boundingRect.bottom, m_position.z());
   glVertex3f(m_boundingRect.right, m_boundingRect.bottom, m_position.z());

   glVertex3f(m_boundingRect.left, m_boundingRect.top, m_position.z());
   glVertex3f(m_boundingRect.left, m_boundingRect.bottom, m_position.z());
   glVertex3f(m_boundingRect.right, m_boundingRect.top, m_position.z());
   glVertex3f(m_boundingRect.right, m_boundingRect.bottom, m_position.z());
  glEnd();
 //  DrawBox(m_position.x(), m_position.y(), m_position.z(), m_size, m_size, m_size, 8);
 glPopMatrix();
}

void Block::DoCollision(GameObject* obj){
 GameObject* t = this;   // I modified this to see for sure that it was causing the mistake.
// obj->DoCollision(NULL); // Just revert it back to 
/*
void Block::DoCollision(GameObject* obj){  
       obj->DoCollision(this);  
    }  
    */

}
Ether
  • 53,118
  • 13
  • 86
  • 159
Justin
  • 13
  • 2

1 Answers1

4

Stack overflow usually comes from infinite recursion. I'm having trouble parsing your question, but here's a guess:

void Block::DoCollision(GameObject* obj){
  if (this != obj) {
    obj->DoCollision(this);
  }
}
Stephen
  • 47,994
  • 7
  • 61
  • 70
  • That did not fix the problem. the stack overflow still occurs. To restate my question, when I only create a single instance of the class "Block", my engine will run perfectly fine and it detects collision perfectly. However, once I create two instances of the "Block", the code causes a stack overflow. When I debug the application, it crashes at obj->DoCollision(this);. The blocks never collide with each other since I programmed them to only collide with the player. I tried your previous answer to no avail. Any other suggestions? – Justin Apr 04 '10 at 04:54
  • After trying a different combinations of your answer, I managed to get it working by using two conditions. if(this != obj && obj->m_type != GameObject::TYPE_OBSTACLE) Looks like I have to rebuild my collision detection since it is giving me hell over that. Thanks man, you were a big help! – Justin Apr 04 '10 at 05:04
  • You will still have this problem if two non-obstacles collide. The infinite recursion is because A's DoCollision method calls B's DoCollision method, which call's A's DoCollision method, and so on... Rather than calling DoCollision inside itself, I would call it once for both sides in your collision detection loop. – Evan Rogers Apr 04 '10 at 11:44
  • Each object that inherits the DoCollision method has it's own version. It is a virtual function so I just superimpose the function on top of the original. The blocks are the only object type that call DoCollision(), and the blocks will never collide since they are stationary. – Justin Apr 04 '10 at 15:27
  • Ah, I see. Well, the callstack window in your debugger will tell the whole story. Good luck! – Evan Rogers Apr 04 '10 at 22:27