/* * Copyright (C) 2017-2019 Christopher J. Howard * * This file is part of Antkeeper Source Code. * * Antkeeper Source Code is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Antkeeper Source Code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Antkeeper Source Code. If not, see . */ #include "tool-system.hpp" ToolSystem::ToolSystem(ComponentManager* componentManager): System(componentManager), tools(componentManager), picked(false) { tools.addGroupObserver(this); } ToolSystem::~ToolSystem() {} void ToolSystem::update(float t, float dt) { pick(); auto members = tools.getMembers(); for (const ToolGroup::Member* member: *members) { ModelComponent* model = std::get<0>(member->components); ToolComponent* tool = std::get<1>(member->components); TransformComponent* transform = std::get<2>(member->components); model->model.setActive(tool->active); if (picked) { transform->transform.translation = mouseWorldPosition; } } picked = false; } void ToolSystem::setPickingCamera(const Camera* camera) { pickingCamera = camera; } void ToolSystem::setPickingViewport(const Vector4& viewport) { pickingViewport = viewport; } void ToolSystem::pick() { Vector3 mouseNear = pickingCamera->unproject(Vector3(mouseScreenPosition, 0.0f), pickingViewport); Vector3 mouseFar = pickingCamera->unproject(Vector3(mouseScreenPosition, 1.0f), pickingViewport); Ray pickingRay; pickingRay.origin = mouseNear; pickingRay.direction = glm::normalize(mouseFar - mouseNear); Plane pickingPlane(Vector3(0.0f, 1.0f, 0.0f), Vector3(0.0f)); auto pickingIntersection = pickingRay.intersects(pickingPlane); picked = std::get<0>(pickingIntersection); if (picked) { mouseWorldPosition = pickingRay.extrapolate(std::get<1>(pickingIntersection)); } } void ToolSystem::memberRegistered(const ToolGroup::Member* member) { ToolComponent* tool = std::get<1>(member->components); tool->active = false; } void ToolSystem::memberUnregistered(const ToolGroup::Member* member) {} void ToolSystem::handleEvent(const MouseMovedEvent& event) { mouseScreenPosition = Vector2(event.x, pickingViewport[3] - event.y); }