블로그 이미지
fiadot_old

칼퇴근을 위한 게임 서버 개발 방법론에 대한 심도있는 고찰 및 성찰을 위한 블로그!

Rss feed Tistory
Technical Article 2004. 10. 14. 13:59

두 강체간의 입사각, 입사속도에 따른 충돌후 반사각,속도 구하기

#ifndef MAX
   #define  MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#endif

#ifndef MIN
   #define  MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
#endif


typedef struct _FIA_POINT
{
        int x;
        int y;
} FIA_POINT;

#define BIG_TILE_SIZE        ROTATE_CHR_SIZE
#define SMALL_TILE_SIZE        12


#define DOT_PRODUCT(ux,uy,vx,vy) ((ux)*(vx) + (uy)*(vy))


void        CollisionResponse(void *pv, BALLSTATE *pBallState, int nStage, int nMapAngle)
{
        PCAMELTRYApp        pApp = (PCAMELTRYApp)pv;
        
        //
        // 1. 공의 위치(다음번에 이동될)에 타일이 있는지 체크
        //

        FIA_POINT        ptAbsPos;
// #ifndef _DEBUG
//        ptAbsPos.x = MIN(MAX((pBallState->posX/ PRECISION + pBallState->vX )/BIG_TILE_SIZE , 0),CX_STAGE);        
//        ptAbsPos.y = MIN(MAX((pBallState->posY/ PRECISION + pBallState->vY )/BIG_TILE_SIZE , 0),CY_STAGE);
// #else
//        ptAbsPos.x = ((pBallState->posX) / PRECISION + 24 + pBallState->vX ) / BIG_TILE_SIZE;        
//        ptAbsPos.y = ((pBallState->posY) / PRECISION + 24 + pBallState->vY ) / BIG_TILE_SIZE;

        ptAbsPos.x = (pBallState->posX + pBallState->vX ) / PRECISION / BIG_TILE_SIZE;        
        ptAbsPos.y = (pBallState->posY + pBallState->vY ) / PRECISION / BIG_TILE_SIZE;

// #endif
        
        if ( 0 == g_cStageMap[nStage][ptAbsPos.y][ptAbsPos.x] )
                return;        // 충돌되는 타일 없다!
        
        
        FIA_POINT ptScroll;
        ptScroll.x = pApp->ScrollOffsetX / PRECISION;        // 스크롤 값
        ptScroll.y = pApp->ScrollOffsetY / PRECISION;

        FIA_POINT ptCollPixel;        // 충돌픽셀 위치
        ptCollPixel.x = 0;
        ptCollPixel.y = 0;

        // 이미지에서 위치에 다른 값 검색 (?)
        FIA_POINT ptScreenImgPos;        // 스크린 화면에 좌표에 해당하는거 얻어냄( 절대 좌표에서 스크린좌표-상대좌표 로 변환)
//        ptScreenImgPos.x = ptAbsPos.x * BIG_TILE_SIZE - ptScroll.x;
//        ptScreenImgPos.y = ptAbsPos.y * BIG_TILE_SIZE - ptScroll.y;
//        ptScreenImgPos.x = ptAbsPos.x;
//        ptScreenImgPos.y = ptAbsPos.y;

        ptScreenImgPos.x = (pBallState->posX + pBallState->vX ) / PRECISION - ptScroll.x;
        ptScreenImgPos.y = (pBallState->posY + pBallState->vY ) / PRECISION - ptScroll.y;


        NativeColor ncClr;
        RGBVAL                rgb;
        
        int        nCollNorX = 0;
        int        nCollNorY = 0;
        int        nCollDist = 0;
        
        bool bFound = FALSE;


        nCollNorX = (pBallState->posX/PRECISION - ptAbsPos.x*BIG_TILE_SIZE)+1;
        nCollNorY = (pBallState->posY/PRECISION - ptAbsPos.y*BIG_TILE_SIZE)+1;
        nCollDist = sqrt(nCollNorX * nCollNorX + nCollNorY * nCollNorY);

        bFound = TRUE;
        
//                
//                //
//                // 2. 타일과 공의 충돌픽셀 체크
//                //
//                for(int nY = ptScreenImgPos.y ; nY < ptScreenImgPos.y + BIG_TILE_SIZE ; nY++ )
//                {
//                        if ( TRUE == bFound )
//                                break;
//                        
//                        for(int nX = ptScreenImgPos.x ; nX < ptScreenImgPos.x + BIG_TILE_SIZE ; nX++ )
//                        {                                        
//                                IBITMAP_GetPixel(pApp->ddbBuffer[ROTATE_BUFFER], nX, nY, &ncClr);        // BG_BUFFER맞나?                
//                                rgb = IBITMAP_NativeToRGB(pApp->ddbBuffer[ROTATE_BUFFER], ncClr);
//
//                                if ( rgb != CLEARCOLOR )                // 해당 위치에 타일 픽셀이 있다.
//                                {                                                                
//                                        nCollNorX = (pBallState->posX/PRECISION - ptScroll.x - nX);
//                                        nCollNorY = (pBallState->posY/PRECISION - ptScroll.y - nY);
//                                        nCollDist = sqrt(nCollNorX * nCollNorX + nCollNorY * nCollNorY);
//
//                                        // 공과 충돌
//                                        if ( nCollDist == 12) // 공 위치에서 r=12 주변 만큼 체크
//                                        {
//                                                ptCollPixel.x = nX + ptScroll.x;
//                                                ptCollPixel.y = nY + ptScroll.y;
//                                                if ( nCollDist == 0 )
//                                                        nCollDist = 1;
//                                                bFound = TRUE;
//                                                break;
//                                        }
//                                }
//                        }
//
//
//                }


        if ( FALSE == bFound )
                return;        // 충돌되는 픽셀이 없다~
        
        //
        // 3. 반사각과 충돌후 속도 계산
        //

        // 충돌노멀벡터 normalize 해주고~
        nCollNorX /= nCollDist;
        nCollNorY /= nCollDist;

        // 접선에 대한 노멀벡터
        int tabx =  -nCollNorX;
        int taby =  nCollNorY;

        // 반사각및 충돌후 속도 구하는 부분  2(N dot L) - L
        int vait = DOT_PRODUCT(pBallState->vX, pBallState->vY, tabx, taby);
        int vain = DOT_PRODUCT(pBallState->vX, pBallState->vY, nCollNorX, nCollNorY);
        int vbit = DOT_PRODUCT(3, 3, tabx, taby);                                // 2, 2는 벽의 노멀벡터에 해당하는 값으로 치환해야함
        int vbin = DOT_PRODUCT(3, 3, nCollNorX, nCollNorY);                // = 벽(타일)의 중점과 충돌픽셀의 벡터 = 노멀벡터에 해당

        int vafn = vbin*2 / 2;
        int vaft = vait;

        int xfa = vafn*nCollNorX + vaft*tabx;
        int yfa = vafn*nCollNorY + vaft*taby;

        // 이단계에서 각에 대해 변환후 변수 치환
        // 속도 적용
//        pBallState->vX = (xfa * pApp->g_sin[nMapAngle]) / PRECISION;
//        pBallState->vY = (yfa * pApp->g_cos[nMapAngle]) / PRECISION;
        
//        pBallState->vX = xfa;
//        pBallState->vY = yfa;

        pBallState->vX = (xfa * pApp->g_sin[nMapAngle]) / PRECISION;
        pBallState->vY = (yfa * pApp->g_cos[nMapAngle]) / PRECISION;        


        // 속도에 따른 위치 이동
        pBallState->posX += pBallState->vX;
        pBallState->posY += pBallState->vY;        
}
,
TOTAL TODAY