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);  
    }  
    */

}

1 Answer 1

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);
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

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?
After trying a different combinations of your answer, I managed to get it working by using two conditions. <code>if(this != obj && obj->m_type != GameObject::TYPE_OBSTACLE)</code> Looks like I have to rebuild my collision detection since it is giving me hell over that. Thanks man, you were a big help!
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.
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.
Ah, I see. Well, the callstack window in your debugger will tell the whole story. Good luck!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.