🧠 개념

🔷 AABB (Axis-Aligned Bounding Box)

  • 축 정렬 박스 충돌체.
  • x, y, z의 축과 항상 평행한 박스.
  • 연산이 매우 간단하고 빠름.
  • 회전이 없는 물체 또는 정적인 오브젝트에 적합.

🔶 OBB (Oriented Bounding Box)

  • 회전 가능한 박스 충돌체.
  • 축과 일치하지 않아도 됨.
  • 박스 자체가 회전 가능하기 때문에 정밀한 충돌 판정 가능.
  • 회전이 잦은 오브젝트, 복잡한 판정을 요구할 때 사용.

⚖️ 성능을 중시하면 AABB, 정확도를 원하면 OBB!


🔨 충돌 박스 클래스 만들기

1. BaseCollider 상속한 AABBBoxCollider, OBBBoxCollider 만들기

폴더 위치: Engine/04. Component/Collision

// AABBBoxCollider.h
class AABBBoxCollider : public BaseCollider {
public:
	AABBBoxCollider();
	virtual ~AABBBoxCollider();

	virtual void Update() override;
	virtual bool Intersects(Ray& ray, OUT float& distance) override;
	virtual bool Intersects(shared_ptr<BaseCollider>& other) override;

	BoundingBox& GetBoundingBox() { return _boundingBox; }

private:
	BoundingBox _boundingBox;
};
// OBBBoxCollider.h
class OBBBoxCollider : public BaseCollider {
public:
	OBBBoxCollider();
	virtual ~OBBBoxCollider();

	virtual void Update() override;
	virtual bool Intersects(Ray& ray, OUT float& distance) override;
	virtual bool Intersects(shared_ptr<BaseCollider>& other) override;

	BoundingOrientedBox& GetBoundingBox() { return _boundingBox; }

private:
	BoundingOrientedBox _boundingBox;
};

🧪 충돌 박스 사용 예시

2. 오브젝트에 충돌체 붙이기

auto collider = make_shared<AABBBoxCollider>();
collider->GetBoundingBox().Extents = Vec3(0.5f);
obj->AddComponent(collider);
  • Extents는 크기 설정.
  • Vec3(0.5f)이면 큐브는 1x1x1 사이즈.

OBB인 경우에는 Orientation도 설정 필요:

collider->GetBoundingBox().Orientation = Quaternion::CreateFromYawPitchRoll(45, 0, 0);

🧭 움직이는 오브젝트 추가

class MoveScript : public MonoBehaviour {
public:
	virtual void Update() override {
		auto pos = GetTransform()->GetPosition();
		pos.x -= DT * 1.0f;
		GetTransform()->SetPosition(pos);
	}
};
  • Sphere에 붙여서 왼쪽으로 이동하게 만들고, 고정된 Cube와 충돌 유도.

💥 충돌 판정 로직 구현

3. Collider별로 Intersects(shared_ptr<BaseCollider>& other) 오버라이드

bool AABBBoxCollider::Intersects(shared_ptr<BaseCollider>& other) {
	switch (other->GetColliderType()) {
	case ColliderType::Sphere:
		return _boundingBox.Intersects(dynamic_pointer_cast<SphereCollider>(other)->GetBoundingSphere());
	case ColliderType::AABB:
		return _boundingBox.Intersects(dynamic_pointer_cast<AABBBoxCollider>(other)->GetBoundingBox());
	case ColliderType::OBB:
		return _boundingBox.Intersects(dynamic_pointer_cast<OBBBoxCollider>(other)->GetBoundingBox());
	}
	return false;
}
  • SphereCollider, AABBBoxCollider, OBBBoxCollider 각각 이 방식으로 구현.
  • 다형성 덕분에 객체가 어떤 타입이든 충돌 가능.

🔁 모든 오브젝트 충돌 체크하기

void Scene::CheckCollision() {
	vector<shared_ptr<BaseCollider>> colliders;
	for (auto& obj : _objects) {
		if (auto collider = obj->GetCollider())
			colliders.push_back(collider);
	}

	for (int i = 0; i < colliders.size(); ++i) {
		for (int j = i + 1; j < colliders.size(); ++j) {
			if (colliders[i]->Intersects(colliders[j])) {
				// 여기에 OnCollisionEnter 등을 호출 가능
				int a = 3; // Breakpoint 설정!
			}
		}
	}
}
  • 프레임마다 충돌체끼리 전수 검사 (Brute Force 방식).
  • 간단한 시뮬레이션이나 학습 목적에 적합.

🎮 최종 시나리오

  • Cube는 회전 가능 or 불가능한 상태에서 AABB 또는 OBB를 사용.
  • Sphere는 MoveScript로 이동 → 충돌 시 판정.
  • Picking도 가능 (클릭 시 제거).
  • 충돌은 CheckCollision()에서 일괄 처리.

profile
李家네_공부방

0개의 댓글