// Copyright (c) 2022 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "dawnlibs.hpp" #include "assert/assert.hpp" #include "util/flag.hpp" namespace Dawn { class SceneItem; class Transform { private: // Local (real) values glm::vec3 localPosition; glm::vec3 localScale; glm::quat localRotation; // Cached (non-real) values glm::mat4 transformLocal; glm::mat4 transformWorld; // glm::vec3 position; // glm::vec3 scale; // glm::quat rotation; // Heirarchy Transform *parent = nullptr; std::vector children; // Hidden methods void updateLocalValuesFromLocalTransform(); void updateLocalTransformFromLocalValues(); void updateWorldTransformFromLocalTransform(); void updateLocalTransformFromWorldTransform(); void updateChildrenTransforms(); public: SceneItem *item; /** * Constructs a new transform instance. Currently I have bound transforms * to their parent SceneItem, but in future I may allow them to become * disconnected from each other, for example I really could use a special * transform designed purely for UI elements, since they don't act like * normal scene items, but for now Transforms and SceneItems are 1:1 * * @param item Item that this transform belongs to. */ Transform(SceneItem *item); /** * Orients this transform to look at a given point in world space. * * @param position Position of the origin of this transform. * @param look Position in world space this transform looks at. */ void lookAt(glm::vec3 position, glm::vec3 look); void lookAt(glm::vec3 position, glm::vec3 look, glm::vec3 up); /** * Returns the local position (position relative to "my parent"). * @return The 3D local position in parent-relative space. */ glm::vec3 getLocalPosition(); /** * Update / Set the local position of this transform relative to my parent * @param position Position to set for the local transform. */ void setLocalPosition(glm::vec3 position); /** * Retusn the scale of this item, relative to my parent. * @return 3D Scale vector of this item in parent-relative space. */ glm::vec3 getLocalScale(); /** * Set the local scale of this item. * @param scale Scale of this item, relative to its parent. */ void setLocalScale(glm::vec3 scale); /** * Returns the local rotation for this transform. * @return The local rotation (parent-relative). */ glm::quat getLocalRotation(); /** * Set the local (parent-relative) rotation for this transform. * @param rotation Rotation in parent relative space. */ void setLocalRotation(glm::quat rotation); /** * Returns the transform matrix for this transform, in parent-relative * space. * @return The transform origin in parent-relative space. */ glm::mat4 getLocalTransform(); /** * Sets the local transform matrix for this transform. * @param transform Local (parent-relative) transform to set. */ void setLocalTransform(glm::mat4 transform); /** * Returns the transformation matrix for this transform, in world-space. * @return The transform origin in world-space. */ glm::mat4 getWorldTransform(); /** * Updates the transform's world-space. * @param transform Sets the transform position in world-space. */ void setWorldTransform(glm::mat4 transform); /** * Updates the transform that this transform is a child of. Will also * handle disconnecting any existing parent. * * @param p Parent that this transform is now a child of. */ void setParent(Transform *p); /** * Returns the parent transform of this transform, or nullptr if there is * no parent for this transform. * @return Pointer to the parent transform, or nullptr. */ Transform * getParent(); /** * Dispose and clenaup this transform, also removes self from parent. */ ~Transform(); friend SceneItem; }; }