Files
face_sdk/vulkan/framework/scene_graph/components/transform.cpp
T

130 lines
2.4 KiB
C++

/* Copyright (c) 2018-2024, Arm Limited and Contributors
*
* 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 "transform.h"
#include "common/glm_common.h"
#include <glm/gtx/matrix_decompose.hpp>
#include "scene_graph/node.h"
namespace vkb
{
namespace sg
{
Transform::Transform(Node &n) :
node{n}
{
}
Node &Transform::get_node()
{
return node;
}
std::type_index Transform::get_type()
{
return typeid(Transform);
}
void Transform::set_translation(const glm::vec3 &new_translation)
{
translation = new_translation;
invalidate_world_matrix();
}
void Transform::set_rotation(const glm::quat &new_rotation)
{
rotation = new_rotation;
invalidate_world_matrix();
}
void Transform::set_scale(const glm::vec3 &new_scale)
{
scale = new_scale;
invalidate_world_matrix();
}
const glm::vec3 &Transform::get_translation() const
{
return translation;
}
const glm::quat &Transform::get_rotation() const
{
return rotation;
}
const glm::vec3 &Transform::get_scale() const
{
return scale;
}
void Transform::set_matrix(const glm::mat4 &matrix)
{
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(matrix, scale, rotation, translation, skew, perspective);
invalidate_world_matrix();
}
glm::mat4 Transform::get_matrix() const
{
return glm::translate(glm::mat4(1.0), translation) *
glm::mat4_cast(rotation) *
glm::scale(glm::mat4(1.0), scale);
}
glm::mat4 Transform::get_world_matrix()
{
update_world_transform();
return world_matrix;
}
void Transform::invalidate_world_matrix()
{
update_world_matrix = true;
}
void Transform::update_world_transform()
{
if (!update_world_matrix)
{
return;
}
world_matrix = get_matrix();
auto parent = node.get_parent();
if (parent)
{
auto &transform = parent->get_component<Transform>();
world_matrix = transform.get_world_matrix() * world_matrix;
}
update_world_matrix = false;
}
} // namespace sg
} // namespace vkb