// 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" #include "state/StateEvent.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: // I have no idea if I'm keeping this // Event<> eventTransformUpdated; StateEvent<> eventTransformUpdated; 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); /** * Shorthand combined for lookAt and perspectivePixelPerfectDistance * to allow you to create pixel perfect lookAt camera view matricies. * * @param position Position of the camera. Z is for an offset. * @param look Position in world space this transform looks at. * @param viewportHeight Height of the viewport. * @param fov Field of view (in radians). * @return The Z distance that was calculated. */ float_t lookAtPixelPerfect( glm::vec3 position, glm::vec3 look, float_t viewportHeight, float_t fov ); /** * 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 position of the origin of this transform in world-space. * * @return Transform origin in world-space. */ glm::vec3 getWorldPosition(); /** * 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(); /** * Returns true if this transform is a child of the given transform, this * climbs up the heirarchy until it finds a match. * * @param p Transform to check if this transform is a child of. * @return True if this transform is a child of the given transform. */ bool_t isChildOf(Transform *p); /** * Dispose and clenaup this transform, also removes self from parent. */ ~Transform(); friend SceneItem; }; }