본문 바로가기
스터디/OpenGL

[ OpenGL ] 공 두개를 충돌시켜보자

by 알 수 없는 사용자 2019. 10. 31.

( ** 인프런에서 들은 강의 '홍정모의 게임 만들기 연습 문제 패키지'를 통해서 공부한 내용과 연습 문제 풀이입니다. **)

 

#include "Game2D.h"
#include "Examples/PrimitivesGallery.h"
#include "RandomNumberGenerator.h"
#include "RigidCircle.h"
#include <vector>
#include <memory>

namespace jm
{
	class Example : public Game2D
	{
	public:
		RigidCircle rb0, rb1;

		Example()
			: Game2D()
		{
			reset();
		}

		void reset()
		{
			// Initial position and velocity
			rb0.pos = vec2(-0.8f, 0.3f);
			rb0.vel = vec2(5.0f, 0.0f);
			rb0.color = Colors::hotpink;
			rb0.radius = 0.1f;
			rb0.mass = 1.0f;

			rb1.pos = vec2(0.8f, 0.3f);
			rb1.vel = vec2(-5.0f, 0.0f);
			rb1.color = Colors::yellow;
			rb1.radius = 0.1f;
			rb1.mass = rb0.mass * std::pow(rb1.radius / rb0.radius, 2.0f);
		}

		void drawWall()
		{
			setLineWidth(5.0f);
			drawLine(Colors::blue, { -1.0f, -1.0f }, Colors::blue, { 1.0f, -1.0f });
			drawLine(Colors::blue, { 1.0f, -1.0f }, Colors::blue, { 1.0f, 1.0f });
			drawLine(Colors::blue, { -1.0f, -1.0f }, Colors::blue, { -1.0f, 1.0f });
		}

		void update() override
		{
			const float dt = getTimeStep() * 0.4f;
			const float epsilon = 0.5f; // 반발 계수

			// physics update
			rb0.update(dt);
			rb1.update(dt);

			// check collision between two rigid bodies
			const float distance = (rb0.pos - rb1.pos).getMagnitude();

			if (distance <= rb0.radius + rb1.radius)
			{
				// compute impulse
				const auto vel_rel = rb0.vel - rb1.vel;
				const auto normal = -(rb1.pos - rb0.pos) / (rb1.pos - rb0.pos).getMagnitude();

				if (vel_rel.getDotProduct(normal) < 0.0f) // approaching
				{
					const auto impulse = normal * -(1.0f + epsilon) * vel_rel.getDotProduct(normal) /
						((1.0f / rb0.mass) + (1.0f / rb1.mass));

					// update velocities of two bodies
					rb0.vel += impulse / rb0.mass;
					rb1.vel -= impulse / rb1.mass;
				}
			}

			// draw
			drawWall();
			rb0.draw();
			rb1.draw();

			// reset button
			if (isKeyPressedAndReleased(GLFW_KEY_R)) reset();
		}

	};
}

int main(void)
{
	jm::Example().run();

	return 0;
}

 

 

공 두 개를 충돌시켜보자.mp4
1.21MB

 

 

**** 키워드 : 법선 벡터, 상대 속도, 충격량, 뉴턴의 제 3법칙, 내적, 방향벡터 ****