1#include "Foundation/Logging/Logger.h"
3#include "TransformSystem.h"
7#include <glm/mat4x4.hpp>
8#include <glm/ext/quaternion_float.hpp>
9#include <glm/gtx/matrix_decompose.hpp>
11#include "Services/Variables.h"
13#include "Utilities/Parallel.h"
22 const auto & transformState = system->getData<
TransformState>(component);
24 bool componentChanged = !transformState.cached || component->hasChanged();
26 if(
auto * parentTransform = component->parent.resolveComponent<
TransformComponent>(); parentTransform) {
27 return componentChanged || transformChainChanged(system, parentTransform);
29 return componentChanged;
40 TransformState & transformState = this->getData<TransformState>(&component);
42 transformState.cached = !transformChainChanged(
this, &component);
43 transformState.changed = !transformState.cached;
50 updateLocalTransform(component);
56 for (
auto & component :
pool) {
57 TransformState & transformState = this->getData<TransformState>(&component);
59 transformState.cached = !transformChainChanged(
this, &component);
60 transformState.changed = !transformState.cached;
63 for (
auto & component :
pool) {
64 if (component.hasChanged()) {
65 updateLocalTransform(component);
71 CpuInstrumentationScope(SCOPE_SYSTEMS,
"TransformSystem::updateLocalToWorldTransform");
72 for (
auto & component :
pool) {
73 updateLocalToWorldTransform(component);
78void Cogs::Core::TransformSystem::handleOriginUpdate(
class Context* )
80 if (origin.x == originUpdate.x && origin.y == originUpdate.y && origin.z == originUpdate.z) {
86 origin = originUpdate;
87 for (
auto& component : pool) {
88 component.setChanged();
92void Cogs::Core::TransformSystem::setLocalTransform(
TransformComponent* component,
const glm::mat4& matrix)
104 float uniformScale = std::cbrt(std::abs(glm::determinant(glm::mat3(matrix))));
105 float reciprocalUniformScale = 1.f / uniformScale;
106 if (std::isfinite(reciprocalUniformScale)) {
107 glm::mat4 conditionedMatrix = matrix * glm::mat4(reciprocalUniformScale, 0.f, 0.f, 0.f,
108 0.f, reciprocalUniformScale, 0.f, 0.f,
109 0.f, 0.f, reciprocalUniformScale, 0.f,
113 glm::vec4 perspective;
115 conditionedMatrix, component->transform.trs.
scale, component->transform.trs.
rotation, component->transform.trs.
position, skew, perspective)) {
119 if (std::numeric_limits<float>::epsilon() <= dot(skew, skew)) {
120 LOG_WARNING(logger,
"Transform matrix contains skew, which is not supported, using matrix directly. Check your models.");
121 component->transform.
matrix = matrix;
124 else if (
auto t = perspective - glm::vec4(0, 0, 0, 1); std::numeric_limits<float>::epsilon() <= dot(t, t)) {
125 LOG_WARNING(logger,
"Transform matrix contains perspective, which is not supported, using matrix directly. Check your models.");
126 component->transform.
matrix = matrix;
132 component->transform.trs.
scale *= uniformScale;
137 LOG_WARNING(logger,
"Failed to decompose matrix, using matrix directly and position/scale/rotation will have no effect. Check your models.");
138 component->transform.
matrix = matrix;
143 LOG_ERROR(logger,
"Transform matrix probably totally broken, ignoring. Check your models.");
144 component->transform.trs.
position = glm::vec3(0.f);
145 component->transform.trs.
rotation = glm::quat();
146 component->transform.trs.
scale = glm::vec3(1.f);
149 getLocalTransform(component) = matrix;
154 getData<TransformState>(component).cached =
false;
157void Cogs::Core::TransformSystem::updateLocalToWorldTransform(
const TransformComponent & component,
bool dirty)
159 auto & transformState = getData<Core::TransformState>(&component);
161 if (transformState.cached && !dirty)
return;
163 if (dirty) updateLocalTransform(component);
168 updateLocalToWorldTransform(*parent, dirty);
170 getLocalToWorld(&component) = getLocalToWorld(parent) * getLocalTransform(&component);
172 getLocalToWorld(&component) = getLocalTransform(&component);
175 transformState.changed =
true;
176 transformState.cached =
true;
void resetCarryChanged()
Reset the CarryChanged flag. Called at start of redraw. See ComponentFlags::CarryChanged.
void resetChanged()
Resets the changed state of the component, respecting any carry state set.
Context * context
Pointer to the Context instance the system lives in.
void update()
Updates the system state to that of the current frame.
ComponentPool< ComponentType > pool
Pool of components managed by the system.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
std::unique_ptr< class TaskManager > taskManager
TaskManager service instance.
std::unique_ptr< class Engine > engine
Engine instance.
Log implementation class.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
ComponentType * resolveComponent() const