openGL 헬리콥터 시뮬레이터

sanghoon·2022년 5월 11일
0
post-custom-banner

구현사항

  1. 헬리콥터의 이동
    • 마우스 드래그에 따라 헬리콥터의 방향이 회전됨
    • wasd 입력에 따라 헬리콥터가 원하는 방향으로 움직임
    • enter키를 누르면 헬리콥터의 날개가 회전/정지함
    • q/e 키를 누르면 헬리콥터가 상승/하강함
  2. 쉐이더 레벨
    • 헬리콥터의 highlight 부분이 보임

구현방식

  • 마우스 드래그에 따른 헬리콥터 방향 회전
void computeMouseRotates() {

	// glfwGetTime is called only once, the first time this function is called
	static double lastTime = glfwGetTime();

	// Compute time difference between current and last frame
	double currentTime = glfwGetTime();
	float deltaTime = float(currentTime - lastTime);

	// Get mouse position	
	glfwGetCursorPos(window, &xpos, &ypos);

	horizontalAngle = 0.0;
	verticalAngle = 0.0;

	// Compute new orientation
	if (xpos < xpos_prev)
		horizontalAngle = -deltaTime * mouseSpeed;
	else if (xpos > xpos_prev)
		horizontalAngle = deltaTime * mouseSpeed;
	else
		horizontalAngle = 0.0;
	
	if (ypos < ypos_prev)
		verticalAngle = -deltaTime * mouseSpeed;
	else if (ypos > ypos_prev)
		verticalAngle = deltaTime * mouseSpeed;
	else
		verticalAngle = 0.0;
		
	G_ModelMatrix *= glm::eulerAngleYXZ(horizontalAngle, verticalAngle, 0.0f);

	xpos_prev = xpos;
	ypos_prev = ypos;

	// For the next frame, the "last time" will be "now"
	lastTime = currentTime;
}
  • 키보드 입력에 따른 헬리콥터 이동 구현
void computeKeyboardTranslates(bool &isPropellerRotating)
{
	static double lastTime = glfwGetTime();
	double currentTime = glfwGetTime();
	float deltaTime = float(currentTime - lastTime);

	// Direction : Spherical coordinates to Cartesian coordinates conversion	
	glm::vec3 right = glm::vec3(0.0f, 0.0f, -1.0f);
	glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
	glm::vec3 forward = glm::vec3(-1.0f, 0.0f, 0.0f);

	glm::vec3 translateFactor = glm::vec3(0.0f);

	// Move up
	if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {
		if (!isPropellerRotating) return;
        
		translateFactor += up * deltaTime * speed;
		currHeight++;
	}
	// Move down
	if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS && currHeight >= 0) {
		// helicopter cannot thrust down bellow ground 
		if (currHeight < boundary && !isPropellerRotating) return;
		// helocopter cannot go down if propeller is not rotating
        
		translateFactor -= up * deltaTime * speed;
		currHeight--;
	}
	// Move right
	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS && currHeight >= boundary) {
		translateFactor += right * deltaTime * speed;
	}
	// Move left
	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS && currHeight >= boundary) {
		translateFactor -= right * deltaTime * speed;
	}
	// Move forward
	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS && currHeight >= boundary) {
		translateFactor += forward * deltaTime * speed;
	}
	// Move backward
	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS && currHeight >= boundary) {
		translateFactor -= forward * deltaTime * speed;
	}

	G_ModelMatrix *= glm::translate(glm::mat4(1.0f), translateFactor);


	// propeller control
	if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS) {
		if (currHeight > boundary)
        	// propeller must be rotating while flying
			isPropellerRotating;
		else
			isPropellerRotating = !isPropellerRotating;
	}
	if (isPropellerRotating == false)
	{
		// do noting
	}
	else {
		gOrientation += 3.14159f * deltaTime * rotSpeed;
		G_RotateWingMatrix = eulerAngleYXZ(gOrientation, 0.0f, 0.0f);
	}

	lastTime = currentTime;
}

  • 헬리콥터의 highlight 표현
// part of the fragment shader (GLSL)
		// Ambient
		float ambientStrength = 0.5;
		vec3 ambient = ambientStrength * objectColor;

		// Diffuse 
		// dot product of normal vector and light direction
		float diffuseStrength = 0.5;
		vec3 norm = normalize(normal);
		// 정점에서 빛의 위치를 향하는 벡터
		vec3 lightDir = normalize(lightPos - FragPos);
		float diff = max(dot(norm, lightDir), 0.0);
		vec3 diffuse = diffuseStrength * diff * objectColor;

		// Specular
		float specularStrength = 0.5;
		vec3 viewDir = normalize(viewPos - FragPos);
		vec3 reflectDir = reflect(-lightDir, norm);
		float spec = pow(max(dot(viewDir, reflectDir), 0.0), 7);
		vec3 specular = specularStrength * spec * objectColor;

		vec3 result = (ambient + diffuse + specular);
post-custom-banner

0개의 댓글