#ifndef TRANSFORM_NODE_HPP
#define TRANSFORM_NODE_HPP
#include "Constants.hpp"
#include "Node.hpp"
namespace wren {
class TransformNode : public Node {
public:
void setPosition(const glm::vec3 &position) {
mPositionRelative = position;
setMatrixDirty();
}
void setAbsolutePosition(const glm::vec3 &position);
void setOrientation(const glm::quat &orientation) {
mOrientationRelative = orientation;
setMatrixDirty();
}
void setAbsoluteOrientation(const glm::quat &orientation);
void setAbsoluteOrientation(float angle, const glm::vec3 &axis) { setAbsoluteOrientation(glm::angleAxis(angle, axis)); }
void setPositionAndOrientation(const glm::vec3 &position, const glm::quat &orientation) {
mPositionRelative = position;
mOrientationRelative = orientation;
setMatrixDirty();
}
void setOrientation(float angle, const glm::vec3 &axis) { setOrientation(glm::angleAxis(angle, axis)); }
void setAbsoluteScale(const glm::vec3 &scale);
void setScale(const glm::vec3 &scale) {
mScaleRelative = scale;
setMatrixDirty();
}
const bool isMatrixDirty() const { return mIsMatrixDirty; }
const glm::vec3 &relativePosition() const { return mPositionRelative; }
const glm::quat &relativeOrientation() const { return mOrientationRelative; }
const glm::vec3 &relativeScale() const { return mScaleRelative; }
const glm::vec3 &position() const {
TransformNode::update();
return mPositionAbsolute;
}
const glm::quat &orientation() const {
TransformNode::update();
return mOrientationAbsolute;
}
const glm::vec3 &scale() const {
TransformNode::update();
return mScaleAbsolute;
}
const glm::mat4 &matrix() const {
TransformNode::update();
return mMatrix;
}
const glm::mat4 relativeMatrix() const;
virtual void applyTranslation(const glm::vec3 &translation) {
mPositionRelative += translation;
mIsMatrixDirty = true;
}
virtual void applyRotation(const glm::quat &rotation) {
mOrientationRelative = rotation * mOrientationRelative;
mIsMatrixDirty = true;
}
virtual void applyRotation(float angle, const glm::vec3 &axis) {
mOrientationRelative = glm::angleAxis(angle, glm::normalize(axis)) * mOrientationRelative;
mIsMatrixDirty = true;
}
virtual void applyScale(const glm::vec3 &scale) {
mScaleRelative *= scale;
mIsMatrixDirty = true;
}
void setParent(Transform *parent) override;
void setMatrixDirty() const override {
if (mIsMatrixDirty)
return;
Node::setMatrixDirty();
mIsMatrixDirty = true;
}
void update() const override;
protected:
TransformNode();
explicit TransformNode(TransformNode *source);
~TransformNode() {}
private:
mutable bool mIsMatrixDirty;
mutable glm::mat4 mMatrix;
mutable glm::vec3 mPositionAbsolute;
mutable glm::quat mOrientationAbsolute;
mutable glm::vec3 mScaleAbsolute;
glm::vec3 mPositionRelative;
glm::quat mOrientationRelative;
glm::vec3 mScaleRelative;
};
}
#endif