예제 #1
0
glm::vec3 Camera::pickAgainstPlane(float x, float y, const glm::vec4& plane) const {

	int width = 0, height = 0;
	glfwGetWindowSize(glfwGetCurrentContext(), &width, &height);

	glm::vec3 screenPos(x / width * 2 - 1, (y / height * 2 - 1) * -1, -1);

	screenPos.x /= m_projection[0][0];
	screenPos.y /= m_projection[1][1];

	glm::vec3 dir = glm::normalize(m_transform * glm::vec4(screenPos, 0)).xyz();

	float d = (plane.w - glm::dot(m_transform[3].xyz(), plane.xyz()) / glm::dot(dir, plane.xyz()));

	return m_transform[3].xyz() + dir * d;
}
예제 #2
0
Collision falksalt::collides(glm::vec4 rect,
	glm::vec2 start, glm::vec2 end)
{
	std::vector<Collision> collisions(4);

	collisions[0] = intersects(start, end, rect.xy(), rect.xy() + glm::vec2(rect.z, 0));
	collisions[0].side = Side::Up;

	collisions[1] = intersects(start, end, rect.xy() + glm::vec2(0, rect.w),
		rect.xy() + rect.zw());
	collisions[1].side = Side::Down;

	collisions[2] = intersects(start, end, rect.xy(), rect.xy() + glm::vec2(0, rect.w));
	collisions[2].side = Side::Left;

	collisions[3] = intersects(start, end, rect.xy() + glm::vec2(rect.z, 0),
			rect.xy() + rect.zw());
	collisions[3].side = Side::Right;

	return closest(start, collisions);
}
예제 #3
0
glm::vec3 Camera::PickAgainstPlane(float x, float y, const glm::vec4& _plane) {
	int width = 0;
	int height = 0;
	glfwGetWindowSize(glfwGetCurrentContext(), &width, &height);

	glm::vec3 screenPos(x / width * 2 - 1, (y / height * 2 - 1) * -1, -1);

	screenPos.x /= m_projectionTransform[0][0];
	screenPos.y /= m_projectionTransform[1][1];

	glm::vec3 dir = glm::normalize(m_worldTransform * glm::vec4(screenPos, 0)).xyz();

	float d = (_plane.w - glm::dot(m_worldTransform[3].xyz(), _plane.xyz()) / glm::dot(dir, _plane.xyz()));

	if (d >= 0) {
		return m_worldTransform[3].xyz() + dir * d;
	} else {
		return glm::vec3(0);
	}

}
  void TextEngineRenderer::Render() {
    GameState &current_state = updater.GetCurrentState();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    PushMatrix();
    matrix_stack.back() *= glm::scale(glm::mat4(1), glm::vec3(glm::vec2(current_state.zoom * 0.1f), 1.0f));
    matrix_stack.back() *= glm::translate(glm::mat4(1), glm::vec3(-current_state.camera_position, 0));

    const glm::vec2 position = glm::vec2(current_state.player_body->GetPosition().x,
                                         current_state.player_body->GetPosition().y);

    fill = glm::vec4(0.0f, 0.5f, 0.3f, 0.5f);
    for (const auto &area : scene.areas) {
      if (area->invisible) {
        continue;
      }
      if (Shape::kAxisAlignedBoundingBox == area->shape) {
        DrawAxisAlignedBoundingBox(area->aabb);
      } else {
        DrawCircle(area->aabb.center(), area->aabb.radius());
      }
    }
    fill = glm::vec4(1.0f, 0.0f, 0.0f, 0.5f);
    for (const auto &object : scene.objects) {
      if (object->invisible) {
        continue;
      }
      if (Shape::kAxisAlignedBoundingBox == object->shape) {
        DrawAxisAlignedBoundingBox(object->aabb);
      } else {
        DrawCircle(object->aabb.center(), object->aabb.radius());
      }	
    }

    const glm::mat4 normalized_to_reversed = glm::scale(glm::mat4(), glm::vec3(1.0f, -1.0f, 1.0f));
    const glm::mat4 reversed_to_offset = glm::translate(glm::mat4(), glm::vec3(glm::vec2(1.0f), 0.0f));
    const glm::mat4 offset_to_screen = glm::scale(glm::mat4(), glm::vec3(glm::vec2(0.5f), 1.0f));
    const glm::mat4 screen_to_window = glm::scale(glm::mat4(), glm::vec3(width, height, 1.0f));

    const glm::mat4 transform = (screen_to_window * offset_to_screen *
                                 reversed_to_offset * normalized_to_reversed *
                                 model_view * projection * matrix_stack.back());
    const glm::mat4 transform2 = (screen_to_window * offset_to_screen *
                                  reversed_to_offset *
                                  model_view * projection * matrix_stack.back());
    const auto inverse = glm::inverse(transform2);
    const glm::vec4 homogeneous = transform * glm::vec4(position, 0.0f, 1.0f);
    const glm::vec2 transformed = homogeneous.xy() / homogeneous.w;

    fill = glm::vec4(0.5f, 0.5f, 0.6f, 1.0f);
    PushMatrix();
    matrix_stack.back() *= glm::translate(glm::mat4(1), glm::vec3(position, 0));
    matrix_stack.back() *= glm::rotate(glm::mat4(1),
                                       current_state.player_body->GetAngle(),
                                       glm::vec3(0, 0, 1));
    DrawRectangle(glm::vec2(0), glm::vec2(0.25f, 0.5f));
    PopMatrix();
    PopMatrix();
    
    if (edit) {
      MaybeRebuildAttenuationShader();
      if (current_state.selected_item) {
        attenuation3_program.Use();
        attenuation3_program.Uniforms({
          {u8"model_view_inverse", &inverse}
        });
        const auto isaabb3 = Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape;
        glUniform1i(attenuation3_program.GetUniformLocation(u8"selected_isaabb"), isaabb3);
        if (Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape) {
          attenuation3_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.minimum},
            {u8"selected_maximum_or_radius", current_state.selected_item->aabb.maximum},
          });
          CHECK_STATE(!glGetError());
        } else {
          attenuation3_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.center()},
            {u8"selected_maximum_or_radius", glm::vec2(current_state.selected_item->aabb.radius())},
          });
          CHECK_STATE(!glGetError());
        }
        const auto attenuation3_coefficients = glm::vec3(
            current_state.selected_item->base_attenuation,
                current_state.selected_item->linear_attenuation,
                    current_state.selected_item->quadratic_attenuation);
        attenuation3_program.Uniforms({
          {u8"selected_attenuation", attenuation3_coefficients},
        });
        const auto color3 = glm::vec4(0, 0, 0, 0.125);
        attenuation3_program.Uniforms({
          {u8"color", color3}
        });
        attenuation_array.Bind();
        glDrawArrays(attenuation.element_type, 0, attenuation.element_count);
        CHECK_STATE(!glGetError());
        
        attenuation_program.Use();
        attenuation_program.Uniforms({
          {u8"model_view_inverse", &inverse}
        });
        const auto isaabb = Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape;
        glUniform1i(attenuation_program.GetUniformLocation(u8"selected_isaabb"), isaabb);
        if (Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape) {
          attenuation_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.minimum},
            {u8"selected_maximum_or_radius", current_state.selected_item->aabb.maximum},
          });
          CHECK_STATE(!glGetError());
        } else {
          attenuation_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.center()},
            {u8"selected_maximum_or_radius", glm::vec2(current_state.selected_item->aabb.radius())},
          });
          CHECK_STATE(!glGetError());
        }
        const auto attenuation_coefficients = glm::vec3(
            current_state.selected_item->base_attenuation,
                current_state.selected_item->linear_attenuation,
                    current_state.selected_item->quadratic_attenuation);
        attenuation_program.Uniforms({
          {u8"selected_attenuation", attenuation_coefficients},
        });
        const auto color = glm::vec4(0, 0, 0, 0.5);
        attenuation_program.Uniforms({
          {u8"color", color}
        });
        attenuation_array.Bind();
        glDrawArrays(attenuation.element_type, 0, attenuation.element_count);
        CHECK_STATE(!glGetError());
      }
    }

    const auto mouse_position = 2.0f * mouse.get_cursor_position();
    unsigned char mouse_buttons = 0;
    if (mouse.IsButtonDown(GLFW_MOUSE_BUTTON_1)) {
      mouse_buttons |= IMGUI_MBUT_LEFT;
    }
    if (mouse.IsButtonDown(GLFW_MOUSE_BUTTON_2)) {
      mouse_buttons |= IMGUI_MBUT_RIGHT;
    }
    
    if (edit) {
      imguiBeginFrame(mouse_position.x, height - mouse_position.y, mouse_buttons, 0);
      
      for (auto &area : scene.areas) {
        const glm::vec4 homogeneous = transform * glm::vec4(area->aabb.minimum.x, area->aabb.maximum.y, 0.0f, 1.0f);
        const glm::vec2 transformed = homogeneous.xy() / homogeneous.w;
        imguiDrawText(transformed.x, height - transformed.y, IMGUI_ALIGN_LEFT, area->name.c_str(), imguiRGBA(0, 0, 0));
      }
      
      for (auto &object : scene.objects) {
        const glm::vec4 homogeneous = transform * glm::vec4(object->aabb.minimum.x, object->aabb.maximum.y, 0.0f, 1.0f);
        const glm::vec2 transformed = homogeneous.xy() / homogeneous.w;
        imguiDrawText(transformed.x, height - transformed.y, IMGUI_ALIGN_LEFT, object->name.c_str(), imguiRGBA(0, 0, 0));
      }
      
      if (current_state.selected_item) {
        std::ostringstream name, constant, linear, quadratic;
        name << current_state.selected_item->name;
        imguiDrawText(10, height - 50, IMGUI_ALIGN_LEFT, name.str().c_str(), imguiRGBA(0, 0, 0));
        constant << "c: " << current_state.selected_item->base_attenuation;
        imguiDrawText(10, height - 75, IMGUI_ALIGN_LEFT, constant.str().c_str(), imguiRGBA(0, 0, 0));
        linear << "l: " << current_state.selected_item->linear_attenuation;
        imguiDrawText(10, height - 100, IMGUI_ALIGN_LEFT, linear.str().c_str(), imguiRGBA(0, 0, 0));
        quadratic << "q: " << current_state.selected_item->quadratic_attenuation << std::endl;
        imguiDrawText(10, height - 125, IMGUI_ALIGN_LEFT, quadratic.str().c_str(), imguiRGBA(0, 0, 0));
      }
      
      imguiEndFrame();
    }

    imguiRenderGLDraw(width, height);
  }