반응형
빨간 사각형을 Box2D 파란 사각형을 Pixel Texture라고 가정
크게 3가지의 틀로 나누어서 이미지 구성을 하였음
자세한 내용은 코드로 확인
// 박스 To 픽셀 충돌
bool CCollision::CollisionBox2DToPixel(CollisionResult& SrcResult, CollisionResult& DestResult, const Box2DInfo& Src, const PixelInfo& Dest)
{
// 박스 To 박스가 있는지 먼저 판단을 해야한다.
if (!CollisionBox2DToBox2D(SrcResult, DestResult, Src, Dest.Box))
return false;
// 교집합을 구한다.
float Left = Src.Min.x < Dest.Min.x ? Dest.Min.x : Src.Min.x;
float Right = Src.Max.x > Dest.Max.x ? Dest.Max.x : Src.Max.x;
float Bottom = Src.Min.y < Dest.Min.y ? Dest.Min.y : Src.Min.y;
float Top = Src.Max.y > Dest.Max.y ? Dest.Max.y : Src.Max.y;
// 월드 공간에서의 좌 하단 좌표를 구한다.
// 센터에서 절반의 x,y를 빼준다.
Vector2 LB = Dest.Box.Center - Dest.Box.Length;
// 원점에서의 상대 좌표를 구해준다.
Left -= LB.x;
Right -= LB.x;
Bottom -= LB.y;
Top -= LB.y;
// Left와 Bottom은 절대로 0이 되어서는 안된다 예외처리
Left = Left < 0.f ? 0.f : Left;
Bottom = Bottom < 0.f ? 0.f : Bottom;
// Right와 Top은 절대 픽셀이미지의 가로와 세로크기를 넘어서면 안된다.
Right = Right >= (float)Dest.Width ? (float)Dest.Width - 1.f : Right;
Top = Top >= (float)Dest.Height ? (float)Dest.Height - 1.f : Top;
// 이미지는 좌상단부터 시작이기 때문에
// 픽셀공간으로의 좌표를 구해준다.
Top = Dest.Height - Top;
Bottom = Dest.Height - Bottom;
bool Collision = false;
// 교집합 구간을 반복한다.
for (int y = (int)Top; y < (int)Bottom; ++y)
{
for (int x = (int)Left; x < (int)Right; ++x)
{
// 색상정보도 있기 때문에 * 4를 한다
int Index = y * (int)Dest.Width * 4 + x * 4;
// 현재 인덱스의 픽셀이 상대방 박스 안에 존재하는지를 판단한다.
// 현재 픽셀을 월드공간에서의 위치를 구해준다.
// y 가 뒤집혀 있기 때문에 다시 뒤집어서 월드공간에서의 픽셀 위치를 구해준다.
Vector2 PixelWorldPos = LB + Vector2((float)x, (float)Dest.Height - y);
// 충돌이 안되었다면 continue해준다.
// 픽셀이 박스 안에 들어왔는지 체크를 하는것
if (!CollisionBox2DToPoint(SrcResult, DestResult, Src, PixelWorldPos))
continue;
// 통과해서 여기까지 왔다면 체크를 해야한다.
switch (Dest.Type)
{
case PixelCollision_Type::Color_Ignore:
// 픽셀 인덱스의 컬러와 데스트의 컬러색상이 동일하면 Ignore이니깐 continue를 한다
if (Dest.Pixel[Index] == Dest.Color[0] &&
Dest.Pixel[Index + 1] == Dest.Color[1] &&
Dest.Pixel[Index + 2] == Dest.Color[2])
continue;
// 그게 아니라면 충돌이 된것이다.
Collision = true;
break;
case PixelCollision_Type::Color_Confirm:
// 픽셀 인덱스의 컬러와 데스트의 컬러색상이 동일하면 Copnfirm이니깐 Collision을 true한다
if (Dest.Pixel[Index] == Dest.Color[0] &&
Dest.Pixel[Index + 1] == Dest.Color[1] &&
Dest.Pixel[Index + 2] == Dest.Color[2])
Collision = true;
break;
case PixelCollision_Type::Alpha_Ignore:
// 픽셀 인덱스의 알파와 데스트의 알파색상이 동일하면 Ignore이니깐 continue를 한다
if (Dest.Pixel[Index + 3] == Dest.Color[3])
continue;
Collision = true;
break;
case PixelCollision_Type::Alpha_Confirm:
// 픽셀 인덱스의 알파와 데스트의 알파색상이 동일하면 Copnfirm이니깐 Collision을 true한다
if (Dest.Pixel[Index + 3] == Dest.Color[3])
Collision = true;
break;
}
if (Collision)
break;
}
if (Collision)
break;
}
return Collision;
}
반응형
'DX11' 카테고리의 다른 글
01 - 10 ~ 01 - 11 UI충돌 / Sound(FMOD) (0) | 2022.01.12 |
---|---|
Box2D To Point 충돌 (0) | 2022.01.05 |
원 충돌(코드) (0) | 2022.01.02 |
obb 충돌 관련(코드) (0) | 2022.01.02 |
2021-11-29 DX11 DInput관련 (0) | 2021.11.29 |
댓글