2D Collision Detection/Rotation?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
sabaal
Posts: 10
Joined: Mon Mar 20, 2006 10:19 pm
Location: Las Vegas, NV

2D Collision Detection/Rotation?

Post by sabaal »

So, I'm making a 2D game, right? I've noticed that Irrlicht comes with some built-in collision detection for 3D models, but I can't seem to find any equivalent for alpha-ized 2D images. I'd rather it be pixel-precise, instead of using bounding boxes, but I'm not so picky that I won't accept either. Does anyone know if I'm overlooking something, or does anyone have a link to something outside of Irrlicht that I can use?

As a side note, I was wondering if there is a way to rotate an image when drawn in 2D. Doing so would make animating my game so much simpler...
Last edited by sabaal on Wed May 03, 2006 2:41 pm, edited 1 time in total.
Glawe
Posts: 11
Joined: Tue May 02, 2006 9:22 am
Location: Lund / Sweden
Contact:

Post by Glawe »

Acctually i was going to post the exact same question about collition between 2 bitmaps, so if you get an answer to this id be more than happy to :)

/Glawe
Silberdrache
Posts: 9
Joined: Tue May 02, 2006 3:17 pm
Location: Zürich, Switzerland

Post by Silberdrache »

Hi,

I don't know about collision detection in irrlicht yet, but here are some
(hopefully) useful links:

Per box:
http://lazyfooproductions.com/SDL_tutor ... /index.php

Per pixel:
http://lazyfooproductions.com/SDL_tutor ... /index.php

It's for SDL but shows the principles very nice. Have a look.
At least it will give you an idea how it should work.
sabaal
Posts: 10
Joined: Mon Mar 20, 2006 10:19 pm
Location: Las Vegas, NV

Post by sabaal »

Two extraordinarily useful links. Thank you very much. :D
I'll try to implement these methods tonight and post my results tomorrow.
Silberdrache
Posts: 9
Joined: Tue May 02, 2006 3:17 pm
Location: Zürich, Switzerland

Post by Silberdrache »

Hi sabaal,

I'm really curious about your results.

Concerning your rotation question:

If you don't plan to paint and animate each rotation frame by hand
I would suggest using textured 2D-polygons. Should be much easier
to rotate and the look would not be different to "normal" 2D.

Even 2D collision should work. Once again: Let me know about your
results for I'm planning to create some simple 2D-shooter...
sabaal
Posts: 10
Joined: Mon Mar 20, 2006 10:19 pm
Location: Las Vegas, NV

Post by sabaal »

Hmm... I might have a hard time combining per-pixel detection with image rotation. Because all I have to generate from is the source texture, I don't know how I'd figure out where the new region is. I'd have a rotated image, but the collision area would still be oriented the same way as the original.

No solution is coming to mind, but that might just be because it's so early in the morning. :?
Any suggestions?
Silberdrache
Posts: 9
Joined: Tue May 02, 2006 3:17 pm
Location: Zürich, Switzerland

Post by Silberdrache »

Did you consider using a textured 2D-polygon instead of "normal" bitmaps ?

Rotation then would not be a problem anymore and you could even use
irrlicht's own 3D collision functions to handle the 2D polygonal collision.
(A polygon is not more or less then just a part of a 3D body).

For sure per pixel collision detection with bitmap-rotation would
be much more complicated.

I would use boxes. Not only one but a certain number to cover the shape
of the bitmap/sprite more or less accurately. For you know the position
of the boxes you could rotate them "easily" like all other pixel via some
pixel translation. Just an idea :wink:

But nevertheless I'll try to find some usefull hints concerning bitmap-rotation...
Silberdrache
Posts: 9
Joined: Tue May 02, 2006 3:17 pm
Location: Zürich, Switzerland

Post by Silberdrache »

Some links:

Tutorials:

http://www.gamedev.net/reference/articl ... cle811.asp
http://www.leunen.com/cbuilder/rotbmp.html

Code:

http://www.programmersheaven.com/zone10 ... /15441.htm

I hope one day it will be possible to use SDL with irrlicht, because SDL
is very usefull for handling bitmaps. For example it has it's own rotation/
zoom command:

rotozoomSurface(SDL_Surface* surface, double zoom, double angle, int smooth)
jam
Posts: 409
Joined: Fri Nov 04, 2005 3:52 am

Post by jam »

Silberdrache wrote:Some links:
I hope one day it will be possible to use SDL with irrlicht, because SDL
is very usefull for handling bitmaps. For example it has it's own rotation/
zoom command:

rotozoomSurface(SDL_Surface* surface, double zoom, double angle, int smooth)
I'm very sure I have seen at least a couple of posters who have gotten SDL to work with irrlicht.


...here's one

http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=10675
Silberdrache
Posts: 9
Joined: Tue May 02, 2006 3:17 pm
Location: Zürich, Switzerland

Post by Silberdrache »

@jam

Thanks for the hint. I already read this post but was thinking it would not
work. I'll try it out and will post my results here.
Silberdrache
Posts: 9
Joined: Tue May 02, 2006 3:17 pm
Location: Zürich, Switzerland

Post by Silberdrache »

Ok,

I took the source from above and added some SDL pixel-draw function called "render()".

Your VC++ setup to compile should be like this:

Image

Image

Exe-File (needs SDL.dll and irrlicht.dll):

http://www.logikfabrik.de/irrlicht/SDL_irr.exe

Code: Select all


#include <windows.h> 

#include <SDL_getenv.h> 
#include <SDL.h> 
#include <SDL_syswm.h> 

#include <irrlicht.h> 

#pragma comment(lib,"SDL.lib") 
#pragma comment(lib,"SDLmain.lib") 

using namespace irr; 
using namespace core; 
using namespace scene; 
using namespace video; 
using namespace io; 
using namespace gui; 

// Cria janela da SDL 
   SDL_Surface *sdl_window = SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_RESIZABLE); 

void render()
{   
  // Lock surface if needed
  if (SDL_MUSTLOCK(sdl_window)) 
    if (SDL_LockSurface(sdl_window) < 0) 
      return;

  // Ask SDL for the time in milliseconds
  int tick = SDL_GetTicks();

  // Declare a couple of variables
  int i, j, yofs, ofs;

  // Draw to screen
  yofs = 0;
  for (i = 0; i < 480; i++)
  {
    for (j = 0, ofs = yofs; j < 640; j++, ofs++)
    {
      ((unsigned int*)sdl_window->pixels)[ofs] = i * i + j * j + tick;
    }
    yofs += sdl_window->pitch / 4;
  }

  // Unlock if needed
  if (SDL_MUSTLOCK(sdl_window)) 
    SDL_UnlockSurface(sdl_window);

  // Tell SDL to update the whole screen
  SDL_UpdateRect(sdl_window, 0, 0, 640, 480);    
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) 
{ 
   // Iniciando SDL 
   if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0) 
   { 
      MessageBox((HWND)(DWORD)GetActiveWindow(),"Ocorreu erro ao iniciar SDL",SDL_GetError(),MB_OK | MB_ICONERROR | MB_TASKMODAL); 
   } 

    
   HWND sdl_hWnd; 
    
   static SDL_SysWMinfo pInfo; 
   SDL_VERSION(&pInfo.version); 
   SDL_GetWMInfo(&pInfo); 
   sdl_hWnd = pInfo.window; 

   //RECT r; 
   //GetWindowRect(pInfo.window, &r); 
   //SetWindowPos(pInfo.window, 0, r.left, r.top, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 

   //SDL_ShowCursor(SDL_DISABLE); 
   SDL_WM_GrabInput(SDL_GRAB_ON); 
    
   SIrrlichtCreationParameters   params; 
   params.AntiAlias=false; 
   params.Bits=32; 
   params.DriverType=EDT_OPENGL; 
   params.Fullscreen=false; 
   params.Stencilbuffer=false; 
   params.Vsync=false; 
   params.WindowSize=dimension2d<s32>(640,480); 
   params.WindowId = (int)sdl_hWnd; 
    
   IrrlichtDevice *device = createDeviceEx(params); 
   IVideoDriver* driver = device->getVideoDriver(); 
   ISceneManager* smgr = device->getSceneManager(); 
   IGUIEnvironment* guienv = device->getGUIEnvironment(); 

   // Ajustando Texto da Janela 
   SDL_WM_SetCaption("Irrlicht + SDL - Testando INPUT",NULL); 

   // Loop Principal ( INPUT ) 
   SDL_Event evento; 
   SDL_EnableKeyRepeat(0,0); 
    
   SDL_EnableKeyRepeat(1,1); 

   // Fazer teste de input 
   bool sair_programa = false; 
    
   // Teste 
   ISceneNode* node = smgr->addTestSceneNode(); 
    
   node->setScale(vector3df(1,1,1)); 
    
   node->setMaterialFlag(EMF_LIGHTING,false); 
   node->setMaterialFlag(EMF_WIREFRAME,true); 
    
   node->setPosition(vector3df(0,0,100)); 
    
   ICameraSceneNode* camera = smgr->addCameraSceneNode(0,vector3df(0,0,0),vector3df(0,0,100)); 
    
   vector3df rotation; 
   vector3df position = node->getPosition(); 
    
   Uint8 *tecla = SDL_GetKeyState(NULL); 

   while(sair_programa==false) 
   { 
      
	   
	  while (SDL_PollEvent(&evento)) 
      { 

         // Inicia Eventos do INPUT 
         switch (evento.type) 
         { 
            // Quanado Apertar alguma tecla do Teclado 
            case SDL_KEYDOWN : switch(evento.key.keysym.sym){ 
              
             case SDLK_UP : printf("Tecla - Seta para Cima - Foi pressionada \n"); rotation.X++; break; 
             case SDLK_DOWN : printf("Tecla - Seta para Baixo - Foi pressionada \n"); rotation.X--; break; 
             case SDLK_LEFT : printf("Tecla - Seta para Esquerda - Foi pressionada \n"); rotation.Y++; break; 
             case SDLK_RIGHT: printf("Tecla - Seta para Direita - Foi pressionada \n"); rotation.Y--; break; 
             case SDLK_ESCAPE : sair_programa = true; break; 

         } break; 
          
         // Quando Soltar alguma tecla do Teclado 
         case SDL_KEYUP : switch(evento.key.keysym.sym){ 
            
           case SDLK_UP : printf("Tecla - Seta para Cima - Foi solta \n"); break; 
           case SDLK_DOWN : printf("Tecla - Seta para Baixo - Foi solta \n"); break; 
           case SDLK_LEFT : printf("Tecla - Seta para Esquerda - Foi solta \n"); break; 
           case SDLK_RIGHT : printf("Tecla - Seta para Direita - Foi solta \n"); break; 
            
      } break; 
      
      // Quando Pressionar algum botão do Mouse 
      case SDL_MOUSEBUTTONDOWN : switch(((SDL_MouseButtonEvent*)&evento)->button){ 
            
           case SDL_BUTTON_LEFT : printf("Mouse - Botao Esquerdo foi pressionado \n"); break; 
           case SDL_BUTTON_MIDDLE : printf("Mouse - Botao do Meio foi pressionado \n"); break; 
           case SDL_BUTTON_RIGHT : printf("Mouse - Botao Direito foi pressionado \n"); break; 
           case SDL_BUTTON_WHEELUP : printf("Mouse - Scroll Para Cima foi Somado \n"); break; 
           case SDL_BUTTON_WHEELDOWN : printf("Mouse - Scroll Para Baixo foi Somado \n"); break; 
            
      } break; 
      
      // Quando Soltar algum botão do Mouse 
      case SDL_MOUSEBUTTONUP : switch(((SDL_MouseButtonEvent*)&evento)->button){ 
            
           case SDL_BUTTON_LEFT : printf("Mouse - Botao Esquerdo foi solto \n"); break; 
           case SDL_BUTTON_MIDDLE : printf("Mouse - Botao do Meio foi solto \n"); break; 
           case SDL_BUTTON_RIGHT : printf("Mouse - Botao Direito foi solto \n"); break; 
           case SDL_BUTTON_WHEELUP : printf("Mouse - Scroll Para Cima foi Parado \n"); position.Z++; break; 
           case SDL_BUTTON_WHEELDOWN : printf("Mouse - Scroll Para Baixo foi Parado \n"); position.Z--; break; 
            
      } break; 
                        
      // Quando Movimentar o Mouse 
      case SDL_MOUSEMOTION : printf("Mouse - Posicao: [%d, %d] \n", evento.motion.x, evento.motion.y); break; 
                  
         // Quando Encerrar SDL 
         case SDL_QUIT : sair_programa = true; break; 
          
         default: break; 
         } 
          
      // Pega o Estado das Teclas do Teclado 
      tecla = SDL_GetKeyState(NULL);  
      
      // Enquanto a Tecla Estiver Pressionada 
      if (tecla[SDLK_RETURN]) printf("Tecla - Enter - Foi pressionada no momento \n"); 
            
      node->setRotation(rotation); 
      node->setPosition(position); 
      
      driver->beginScene(true, true, SColor(255,0,0,0)); 

      smgr->drawAll(); 
      guienv->drawAll(); 

      driver->endScene();                                                              
      }
	  
      render();

      node->setRotation(rotation); 
      node->setPosition(position); 
      
      driver->beginScene(true, true, SColor(255,0,0,0)); 

      smgr->drawAll(); 
      guienv->drawAll(); 

      driver->endScene();  

   } 
 

   // Libera memária alocada para a Janela 
   SDL_FreeSurface(sdl_window); 

   // Destruindo SDL 
   SDL_Quit(); 
   device->drop(); 

   return 0; 
}

Usage:

Press arrow-keys to rotate the node.

Open Questions:

-the SDL-background is flickering, how can it be fixed ?
-would SDL and irrlicht object collision detection work together ?
-how to clip irrlicht and SDL objects ? How to handle what's in the
front and what's in the background ?

Would be great to mix SDLs 2D functions like 2d rotation and zoom
with irrlicht's 3D functions.
sabaal
Posts: 10
Joined: Mon Mar 20, 2006 10:19 pm
Location: Las Vegas, NV

Post by sabaal »

Wow! I step away for a couple days, and get this when I return. :P

Unfortunately, I'm using KDevelop under Linux, so I can't make much of this VC++ information. And I'd really rather keep things to Irrlicht, for the sake of simplicity. I think I'll continue pursuing that polygon idea, although this texturing crap is confusing me to no end. Does draw2dPolygon even support textures? How? If not, I'd have to use a 3d polygon, right? Man, this is gonna get complicated...
Post Reply