init
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
/* Copyright (c) 2019-2024, Arm Limited and Contributors
|
||||
* Copyright (c) 2020-2024, Andrew Cox, Huawei Technologies Research & Development (UK) Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 the "License";
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "free_camera.h"
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
#include "common/glm_common.h"
|
||||
#include <glm/gtx/euler_angles.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include "scene_graph/components/perspective_camera.h"
|
||||
#include "scene_graph/components/transform.h"
|
||||
#include "scene_graph/node.h"
|
||||
|
||||
namespace vkb
|
||||
{
|
||||
namespace sg
|
||||
{
|
||||
const float FreeCamera::TOUCH_DOWN_MOVE_FORWARD_WAIT_TIME = 2.0f;
|
||||
|
||||
const float FreeCamera::ROTATION_MOVE_WEIGHT = 0.1f;
|
||||
|
||||
const float FreeCamera::KEY_ROTATION_MOVE_WEIGHT = 0.5f;
|
||||
|
||||
const float FreeCamera::TRANSLATION_MOVE_WEIGHT = 3.0f;
|
||||
|
||||
const float FreeCamera::TRANSLATION_MOVE_STEP = 50.0f;
|
||||
|
||||
const uint32_t FreeCamera::TRANSLATION_MOVE_SPEED = 4;
|
||||
|
||||
FreeCamera::FreeCamera(Node &node) :
|
||||
NodeScript{node, "FreeCamera"}
|
||||
{}
|
||||
|
||||
void FreeCamera::update(float delta_time)
|
||||
{
|
||||
glm::vec3 delta_translation(0.0f, 0.0f, 0.0f);
|
||||
glm::vec3 delta_rotation(0.0f, 0.0f, 0.0f);
|
||||
|
||||
float mul_translation = speed_multiplier;
|
||||
|
||||
if (key_pressed[KeyCode::W])
|
||||
{
|
||||
delta_translation.z -= TRANSLATION_MOVE_STEP;
|
||||
}
|
||||
if (key_pressed[KeyCode::S])
|
||||
{
|
||||
delta_translation.z += TRANSLATION_MOVE_STEP;
|
||||
}
|
||||
if (key_pressed[KeyCode::A])
|
||||
{
|
||||
delta_translation.x -= TRANSLATION_MOVE_STEP;
|
||||
}
|
||||
if (key_pressed[KeyCode::D])
|
||||
{
|
||||
delta_translation.x += TRANSLATION_MOVE_STEP;
|
||||
}
|
||||
if (key_pressed[KeyCode::Q])
|
||||
{
|
||||
delta_translation.y -= TRANSLATION_MOVE_STEP;
|
||||
}
|
||||
if (key_pressed[KeyCode::E])
|
||||
{
|
||||
delta_translation.y += TRANSLATION_MOVE_STEP;
|
||||
}
|
||||
if (key_pressed[KeyCode::LeftControl])
|
||||
{
|
||||
mul_translation *= (1.0f * TRANSLATION_MOVE_SPEED);
|
||||
}
|
||||
if (key_pressed[KeyCode::LeftShift])
|
||||
{
|
||||
mul_translation *= (1.0f / TRANSLATION_MOVE_SPEED);
|
||||
}
|
||||
|
||||
if (key_pressed[KeyCode::I])
|
||||
{
|
||||
delta_rotation.x += KEY_ROTATION_MOVE_WEIGHT;
|
||||
}
|
||||
if (key_pressed[KeyCode::K])
|
||||
{
|
||||
delta_rotation.x -= KEY_ROTATION_MOVE_WEIGHT;
|
||||
}
|
||||
if (key_pressed[KeyCode::J])
|
||||
{
|
||||
delta_rotation.y += KEY_ROTATION_MOVE_WEIGHT;
|
||||
}
|
||||
if (key_pressed[KeyCode::L])
|
||||
{
|
||||
delta_rotation.y -= KEY_ROTATION_MOVE_WEIGHT;
|
||||
}
|
||||
|
||||
if (mouse_button_pressed[MouseButton::Left] && mouse_button_pressed[MouseButton::Right])
|
||||
{
|
||||
delta_rotation.z += TRANSLATION_MOVE_WEIGHT * mouse_move_delta.x;
|
||||
}
|
||||
else if (mouse_button_pressed[MouseButton::Right])
|
||||
{
|
||||
delta_rotation.x -= ROTATION_MOVE_WEIGHT * mouse_move_delta.y;
|
||||
delta_rotation.y -= ROTATION_MOVE_WEIGHT * mouse_move_delta.x;
|
||||
}
|
||||
else if (mouse_button_pressed[MouseButton::Left])
|
||||
{
|
||||
delta_translation.x += TRANSLATION_MOVE_WEIGHT * mouse_move_delta.x;
|
||||
delta_translation.y += TRANSLATION_MOVE_WEIGHT * -mouse_move_delta.y;
|
||||
}
|
||||
|
||||
if (touch_pointer_pressed[0])
|
||||
{
|
||||
delta_rotation.x -= ROTATION_MOVE_WEIGHT * touch_move_delta.y;
|
||||
delta_rotation.y -= ROTATION_MOVE_WEIGHT * touch_move_delta.x;
|
||||
|
||||
if (touch_pointer_time > TOUCH_DOWN_MOVE_FORWARD_WAIT_TIME)
|
||||
{
|
||||
delta_translation.z -= TRANSLATION_MOVE_STEP;
|
||||
}
|
||||
else
|
||||
{
|
||||
touch_pointer_time += delta_time;
|
||||
}
|
||||
}
|
||||
|
||||
delta_translation *= mul_translation * delta_time;
|
||||
delta_rotation *= delta_time;
|
||||
|
||||
// Only re-calculate the transform if it's changed
|
||||
if (delta_rotation != glm::vec3(0.0f, 0.0f, 0.0f) || delta_translation != glm::vec3(0.0f, 0.0f, 0.0f))
|
||||
{
|
||||
auto &transform = get_node().get_component<Transform>();
|
||||
|
||||
glm::quat qx = glm::angleAxis(delta_rotation.x, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
glm::quat qy = glm::angleAxis(delta_rotation.y, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
glm::quat orientation = glm::normalize(qy * transform.get_rotation() * qx);
|
||||
|
||||
transform.set_translation(transform.get_translation() + delta_translation * glm::conjugate(orientation));
|
||||
transform.set_rotation(orientation);
|
||||
}
|
||||
|
||||
mouse_move_delta = {};
|
||||
touch_move_delta = {};
|
||||
}
|
||||
|
||||
void FreeCamera::input_event(const InputEvent &input_event)
|
||||
{
|
||||
if (input_event.get_source() == EventSource::Keyboard)
|
||||
{
|
||||
const auto &key_event = static_cast<const KeyInputEvent &>(input_event);
|
||||
|
||||
if (key_event.get_action() == KeyAction::Down ||
|
||||
key_event.get_action() == KeyAction::Repeat)
|
||||
{
|
||||
key_pressed[key_event.get_code()] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_pressed[key_event.get_code()] = false;
|
||||
}
|
||||
}
|
||||
else if (input_event.get_source() == EventSource::Mouse)
|
||||
{
|
||||
const auto &mouse_button = static_cast<const MouseButtonInputEvent &>(input_event);
|
||||
|
||||
glm::vec2 mouse_pos{std::floor(mouse_button.get_pos_x()), std::floor(mouse_button.get_pos_y())};
|
||||
|
||||
if (mouse_button.get_action() == MouseAction::Down)
|
||||
{
|
||||
mouse_button_pressed[mouse_button.get_button()] = true;
|
||||
}
|
||||
|
||||
if (mouse_button.get_action() == MouseAction::Up)
|
||||
{
|
||||
mouse_button_pressed[mouse_button.get_button()] = false;
|
||||
}
|
||||
|
||||
if (mouse_button.get_action() == MouseAction::Move)
|
||||
{
|
||||
mouse_move_delta = mouse_pos - mouse_last_pos;
|
||||
|
||||
mouse_last_pos = mouse_pos;
|
||||
}
|
||||
}
|
||||
else if (input_event.get_source() == EventSource::Touchscreen)
|
||||
{
|
||||
const auto &touch_event = static_cast<const TouchInputEvent &>(input_event);
|
||||
|
||||
glm::vec2 touch_pos{std::floor(touch_event.get_pos_x()), std::floor(touch_event.get_pos_y())};
|
||||
|
||||
if (touch_event.get_action() == TouchAction::Down)
|
||||
{
|
||||
touch_pointer_pressed[touch_event.get_pointer_id()] = true;
|
||||
|
||||
touch_last_pos = touch_pos;
|
||||
}
|
||||
|
||||
if (touch_event.get_action() == TouchAction::Up)
|
||||
{
|
||||
touch_pointer_pressed[touch_event.get_pointer_id()] = false;
|
||||
|
||||
touch_pointer_time = 0.0f;
|
||||
}
|
||||
|
||||
if (touch_event.get_action() == TouchAction::Move && touch_event.get_pointer_id() == 0)
|
||||
{
|
||||
touch_move_delta = touch_pos - touch_last_pos;
|
||||
|
||||
touch_last_pos = touch_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FreeCamera::resize(uint32_t width, uint32_t height)
|
||||
{
|
||||
auto &camera_node = get_node();
|
||||
|
||||
if (camera_node.has_component<Camera>())
|
||||
{
|
||||
if (auto camera = dynamic_cast<PerspectiveCamera *>(&camera_node.get_component<Camera>()))
|
||||
{
|
||||
camera->set_aspect_ratio(static_cast<float>(width) / height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sg
|
||||
} // namespace vkb
|
||||
Reference in New Issue
Block a user