Nuked Transform
This commit is contained in:
		@@ -7,7 +7,6 @@
 | 
			
		||||
target_sources(${DAWN_TARGET_NAME}
 | 
			
		||||
  PRIVATE
 | 
			
		||||
    RenderPipeline.cpp
 | 
			
		||||
    Transform.cpp
 | 
			
		||||
    Tileset.cpp
 | 
			
		||||
    Color.cpp
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -105,7 +105,7 @@ void RenderPipeline::renderSceneCamera(std::shared_ptr<Scene> scene, std::shared
 | 
			
		||||
  // Update shader parameter buffers with current knowledge
 | 
			
		||||
  struct RenderPipelineShaderBufferData shaderBufferData;
 | 
			
		||||
  shaderBufferData.projection = camera->getProjection();
 | 
			
		||||
  shaderBufferData.view = camera->transform->getWorldTransform();
 | 
			
		||||
  shaderBufferData.view = camera->item->getWorldTransform();
 | 
			
		||||
  shaderBuffer.buffer(&shaderBufferData);
 | 
			
		||||
 | 
			
		||||
  // Prepare a render context. This is just a nice way of letting renderables 
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,10 @@ namespace Dawn {
 | 
			
		||||
       * @param scene Scene to render.
 | 
			
		||||
       * @param camera Camera within the scene to render.
 | 
			
		||||
       */
 | 
			
		||||
      virtual void renderSceneCamera(std::shared_ptr<Scene> scene, std::shared_ptr<Camera> camera);
 | 
			
		||||
      virtual void renderSceneCamera(
 | 
			
		||||
        std::shared_ptr<Scene> scene,
 | 
			
		||||
        std::shared_ptr<Camera> camera
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Cleanup a render pipeline that has been initialized.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,195 +0,0 @@
 | 
			
		||||
// Copyright (c) 2022 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "Transform.hpp"
 | 
			
		||||
#include "scene/SceneItem.hpp"
 | 
			
		||||
#include "util/mathutils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
Transform::Transform(SceneItem *item) :
 | 
			
		||||
  transformLocal(1.0f),
 | 
			
		||||
  transformWorld(1.0f)
 | 
			
		||||
{
 | 
			
		||||
  assertNotNull(item, "Transform::Transform: Item cannot be null");
 | 
			
		||||
  
 | 
			
		||||
  this->item = item;
 | 
			
		||||
  this->updateLocalValuesFromLocalTransform();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::updateLocalValuesFromLocalTransform() {
 | 
			
		||||
  glm::vec3 skew;
 | 
			
		||||
  glm::vec4 perspective;
 | 
			
		||||
  glm::decompose(
 | 
			
		||||
    this->transformLocal,
 | 
			
		||||
    this->localScale,
 | 
			
		||||
    this->localRotation,
 | 
			
		||||
    this->localPosition,
 | 
			
		||||
    skew, perspective
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::updateLocalTransformFromLocalValues() {
 | 
			
		||||
  glm::mat4 translate = glm::translate(glm::mat4(1.0), this->localPosition);
 | 
			
		||||
  glm::mat4 rotate = glm::mat4_cast(this->localRotation);
 | 
			
		||||
  glm::mat4 scale = glm::scale(glm::mat4(1.0), this->localScale);
 | 
			
		||||
  this->transformLocal = translate * rotate * scale;
 | 
			
		||||
  this->updateWorldTransformFromLocalTransform();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::updateWorldTransformFromLocalTransform() {
 | 
			
		||||
  auto parent = this->getParent();
 | 
			
		||||
  if(parent != nullptr) {
 | 
			
		||||
    auto newWorld = parent->getWorldTransform();
 | 
			
		||||
    this->transformWorld = newWorld * transformLocal;
 | 
			
		||||
  } else {
 | 
			
		||||
    this->transformWorld = transformLocal;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::updateLocalTransformFromWorldTransform() {
 | 
			
		||||
  glm::mat4 parentMat(1.0f);
 | 
			
		||||
  auto parent = this->getParent();
 | 
			
		||||
  if(parent != nullptr) parentMat = parent->getWorldTransform();
 | 
			
		||||
  this->transformLocal = parentMat / this->transformWorld;
 | 
			
		||||
  this->updateLocalValuesFromLocalTransform();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::updateChildrenTransforms() {
 | 
			
		||||
  auto it = this->children.begin();
 | 
			
		||||
  while(it != this->children.end()) {
 | 
			
		||||
    (*it)->updateWorldTransformFromLocalTransform();
 | 
			
		||||
    ++it;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::lookAt(glm::vec3 pos, glm::vec3 look) {
 | 
			
		||||
  this->lookAt(pos, look, glm::vec3(0, 1, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::lookAt(glm::vec3 pos, glm::vec3 look, glm::vec3 up) {
 | 
			
		||||
  this->setWorldTransform(glm::lookAt(pos, look, up));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float_t Transform::lookAtPixelPerfect(
 | 
			
		||||
  glm::vec3 position, glm::vec3 look, float_t viewportHeight, float_t fov
 | 
			
		||||
) {
 | 
			
		||||
  float_t z = (
 | 
			
		||||
    tanf((mathDeg2Rad(180.0f) - fov) / 2.0f) *
 | 
			
		||||
    (viewportHeight/2.0f)
 | 
			
		||||
  );
 | 
			
		||||
  this->lookAt(glm::vec3(position.x, position.y, position.z + z), look);
 | 
			
		||||
  return z;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::vec3 Transform::getLocalPosition() {
 | 
			
		||||
  return this->localPosition;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::setLocalPosition(glm::vec3 position) {
 | 
			
		||||
  this->localPosition = position;
 | 
			
		||||
  this->updateLocalTransformFromLocalValues();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::vec3 Transform::getLocalScale() {
 | 
			
		||||
  return this->localScale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::setLocalScale(glm::vec3 scale) {
 | 
			
		||||
  this->localScale = scale;
 | 
			
		||||
  this->updateLocalTransformFromLocalValues();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::quat Transform::getLocalRotation() {
 | 
			
		||||
  return this->localRotation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::setLocalRotation(glm::quat rotation) {
 | 
			
		||||
  this->localRotation = rotation;
 | 
			
		||||
  this->updateLocalTransformFromLocalValues();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
glm::mat4 Transform::getLocalTransform() {
 | 
			
		||||
  return this->transformLocal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::setLocalTransform(glm::mat4 transform) {
 | 
			
		||||
  this->transformLocal = transform;
 | 
			
		||||
 | 
			
		||||
  this->updateLocalValuesFromLocalTransform();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::vec3 Transform::getWorldPosition() {
 | 
			
		||||
  return this->transformWorld[3];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::mat4 Transform::getWorldTransform() {
 | 
			
		||||
  return this->transformWorld;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Transform::setWorldTransform(glm::mat4 transform) {
 | 
			
		||||
  this->transformWorld = transform;
 | 
			
		||||
  this->updateLocalTransformFromWorldTransform();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Transform::setParent(Transform *parent) {
 | 
			
		||||
  assertTrue(parent == nullptr || parent != this, "Transform::setParent: Cannot set parent to self");
 | 
			
		||||
  
 | 
			
		||||
  auto currentParent = this->getParent();
 | 
			
		||||
  if(currentParent == parent) return;
 | 
			
		||||
 | 
			
		||||
  if(currentParent != nullptr) {
 | 
			
		||||
    auto it = currentParent->children.begin();
 | 
			
		||||
    while(it != currentParent->children.end()) {
 | 
			
		||||
      if(*it == this) {
 | 
			
		||||
        currentParent->children.erase(it);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      ++it;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this->parent = parent;
 | 
			
		||||
  if(parent != nullptr) parent->children.push_back(this);
 | 
			
		||||
 | 
			
		||||
  this->updateLocalTransformFromWorldTransform();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Transform * Transform::getParent() {
 | 
			
		||||
  return this->parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t Transform::isChildOf(Transform *parent) {
 | 
			
		||||
  Transform *current = this->getParent();
 | 
			
		||||
  while(current != nullptr) {
 | 
			
		||||
    if(current == parent) return true;
 | 
			
		||||
    current = current->getParent();
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Transform::~Transform() {
 | 
			
		||||
  this->setParent(nullptr);
 | 
			
		||||
 | 
			
		||||
  auto it = this->children.begin();
 | 
			
		||||
  while(it != this->children.end()) {
 | 
			
		||||
    (*it)->setParent(nullptr);
 | 
			
		||||
    it = this->children.begin();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,180 +0,0 @@
 | 
			
		||||
// 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<Transform *> 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;
 | 
			
		||||
  };
 | 
			
		||||
} 
 | 
			
		||||
		Reference in New Issue
	
	Block a user