Nuked Transform
This commit is contained in:
		@@ -5,14 +5,19 @@
 | 
			
		||||
 | 
			
		||||
#include "SceneItem.hpp"
 | 
			
		||||
#include "SceneItemComponent.hpp"
 | 
			
		||||
#include "util/mathutils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
SceneItem::SceneItem(Scene *scene, sceneitemid_t id)  : transform(this) {
 | 
			
		||||
SceneItem::SceneItem(Scene *scene, sceneitemid_t id)  :
 | 
			
		||||
  transformLocal(1.0f),
 | 
			
		||||
  transformWorld(1.0f)
 | 
			
		||||
{
 | 
			
		||||
  assertNotNull(scene, "SceneItem::SceneItem: Scene cannot be null");
 | 
			
		||||
  
 | 
			
		||||
  this->id = id;
 | 
			
		||||
  this->scene = scene;
 | 
			
		||||
  this->updateLocalValuesFromLocalTransform();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::init() {
 | 
			
		||||
@@ -63,5 +68,185 @@ void SceneItem::destroy() {
 | 
			
		||||
  this->components.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::updateLocalValuesFromLocalTransform() {
 | 
			
		||||
  glm::vec3 skew;
 | 
			
		||||
  glm::vec4 perspective;
 | 
			
		||||
  glm::decompose(
 | 
			
		||||
    this->transformLocal,
 | 
			
		||||
    this->localScale,
 | 
			
		||||
    this->localRotation,
 | 
			
		||||
    this->localPosition,
 | 
			
		||||
    skew, perspective
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::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 SceneItem::updateWorldTransformFromLocalTransform() {
 | 
			
		||||
  auto parent = this->getParent().lock();
 | 
			
		||||
  if(parent != nullptr) {
 | 
			
		||||
    auto newWorld = parent->getWorldTransform();
 | 
			
		||||
    this->transformWorld = newWorld * transformLocal;
 | 
			
		||||
  } else {
 | 
			
		||||
    this->transformWorld = transformLocal;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SceneItem::updateLocalTransformFromWorldTransform() {
 | 
			
		||||
  glm::mat4 parentMat(1.0f);
 | 
			
		||||
  auto parent = this->getParent().lock();
 | 
			
		||||
  if(parent != nullptr) parentMat = parent->getWorldTransform();
 | 
			
		||||
  this->transformLocal = parentMat / this->transformWorld;
 | 
			
		||||
  this->updateLocalValuesFromLocalTransform();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::updateChildrenTransforms() {
 | 
			
		||||
  auto it = this->children.begin();
 | 
			
		||||
  while(it != this->children.end()) {
 | 
			
		||||
    auto childTrans = it->lock();
 | 
			
		||||
    if(childTrans)  childTrans->updateWorldTransformFromLocalTransform();
 | 
			
		||||
    ++it;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::lookAt(glm::vec3 pos, glm::vec3 look) {
 | 
			
		||||
  this->lookAt(pos, look, glm::vec3(0, 1, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::lookAt(glm::vec3 pos, glm::vec3 look, glm::vec3 up) {
 | 
			
		||||
  this->setWorldTransform(glm::lookAt(pos, look, up));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float_t SceneItem::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 SceneItem::getLocalPosition() {
 | 
			
		||||
  return this->localPosition;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::setLocalPosition(glm::vec3 position) {
 | 
			
		||||
  this->localPosition = position;
 | 
			
		||||
  this->updateLocalTransformFromLocalValues();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::vec3 SceneItem::getLocalScale() {
 | 
			
		||||
  return this->localScale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::setLocalScale(glm::vec3 scale) {
 | 
			
		||||
  this->localScale = scale;
 | 
			
		||||
  this->updateLocalTransformFromLocalValues();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::quat SceneItem::getLocalRotation() {
 | 
			
		||||
  return this->localRotation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::setLocalRotation(glm::quat rotation) {
 | 
			
		||||
  this->localRotation = rotation;
 | 
			
		||||
  this->updateLocalTransformFromLocalValues();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
glm::mat4 SceneItem::getLocalTransform() {
 | 
			
		||||
  return this->transformLocal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::setLocalTransform(glm::mat4 transform) {
 | 
			
		||||
  this->transformLocal = transform;
 | 
			
		||||
 | 
			
		||||
  this->updateLocalValuesFromLocalTransform();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::vec3 SceneItem::getWorldPosition() {
 | 
			
		||||
  return this->transformWorld[3];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
glm::mat4 SceneItem::getWorldTransform() {
 | 
			
		||||
  return this->transformWorld;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItem::setWorldTransform(glm::mat4 transform) {
 | 
			
		||||
  this->transformWorld = transform;
 | 
			
		||||
  this->updateLocalTransformFromWorldTransform();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void SceneItem::setParent(std::shared_ptr<SceneItem> parent) {
 | 
			
		||||
  assertTrue(
 | 
			
		||||
    parent == nullptr || parent != shared_from_this(),
 | 
			
		||||
    "SceneItem::setParent: Cannot set parent to self"
 | 
			
		||||
  );
 | 
			
		||||
  
 | 
			
		||||
  auto currentParent = this->getParent().lock();
 | 
			
		||||
  if(currentParent == parent) return;
 | 
			
		||||
 | 
			
		||||
  if(currentParent != nullptr) {
 | 
			
		||||
    auto it = currentParent->children.begin();
 | 
			
		||||
    while(it != currentParent->children.end()) {
 | 
			
		||||
      auto child = (*it).lock();
 | 
			
		||||
      if(child == shared_from_this()) {
 | 
			
		||||
        currentParent->children.erase(it);
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      ++it;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this->parent = parent;
 | 
			
		||||
  if(parent != nullptr) parent->children.push_back(shared_from_this());
 | 
			
		||||
 | 
			
		||||
  this->updateLocalTransformFromWorldTransform();
 | 
			
		||||
  this->updateChildrenTransforms();
 | 
			
		||||
  this->eventTransformUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::weak_ptr<SceneItem> SceneItem::getParent() {
 | 
			
		||||
  return this->parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t SceneItem::isChildOf(std::shared_ptr<SceneItem> parent) {
 | 
			
		||||
  auto current = this->getParent();
 | 
			
		||||
  std::shared_ptr<SceneItem> currentLocked;
 | 
			
		||||
  while(currentLocked = current.lock()) {
 | 
			
		||||
    if(currentLocked == parent) return true;
 | 
			
		||||
    current = currentLocked->getParent();
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SceneItem::~SceneItem() {
 | 
			
		||||
  this->setParent(nullptr);
 | 
			
		||||
 | 
			
		||||
  auto it = this->children.begin();
 | 
			
		||||
  while(it != this->children.end()) {
 | 
			
		||||
    auto child = (*it).lock();
 | 
			
		||||
    if(child != nullptr) child->setParent(nullptr);
 | 
			
		||||
    it = this->children.begin();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,21 +4,47 @@
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "display/Transform.hpp"
 | 
			
		||||
#include "scene/Scene.hpp"
 | 
			
		||||
#include "util/array.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class SceneItemComponent;
 | 
			
		||||
 | 
			
		||||
  class SceneItem : public StateOwner {
 | 
			
		||||
  class SceneItem :
 | 
			
		||||
    public StateOwner,
 | 
			
		||||
    public std::enable_shared_from_this<SceneItem>
 | 
			
		||||
  {
 | 
			
		||||
    private:
 | 
			
		||||
      std::vector<std::shared_ptr<SceneItemComponent>> components;
 | 
			
		||||
      // 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
 | 
			
		||||
      std::weak_ptr<SceneItem> parent;
 | 
			
		||||
      std::vector<std::weak_ptr<SceneItem>> children;
 | 
			
		||||
 | 
			
		||||
      // Hidden methods
 | 
			
		||||
      void updateLocalValuesFromLocalTransform();
 | 
			
		||||
      void updateLocalTransformFromLocalValues();
 | 
			
		||||
      void updateWorldTransformFromLocalTransform();
 | 
			
		||||
      void updateLocalTransformFromWorldTransform();
 | 
			
		||||
      void updateChildrenTransforms();
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
      Scene *scene;
 | 
			
		||||
      sceneitemid_t id;
 | 
			
		||||
      Transform transform;
 | 
			
		||||
      // I have no idea if I'm keeping this
 | 
			
		||||
      StateEvent<> eventTransformUpdated;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Constructor for a SceneItem. Scene Items should only be called and
 | 
			
		||||
@@ -106,10 +132,16 @@ namespace Dawn {
 | 
			
		||||
       */
 | 
			
		||||
      template<class T>
 | 
			
		||||
      std::shared_ptr<T> findChild() {
 | 
			
		||||
        auto it = this->transform.children.begin();
 | 
			
		||||
        while(it != this->transform.children.end()) {
 | 
			
		||||
          auto child = (*it)->item->getComponent<T>();
 | 
			
		||||
          if(child != nullptr) return child;
 | 
			
		||||
        auto it = this->children.begin();
 | 
			
		||||
        while(it != this->children.end()) {
 | 
			
		||||
          auto childItem = it->lock();
 | 
			
		||||
          if(childItem == nullptr) {
 | 
			
		||||
            ++it;
 | 
			
		||||
            continue;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          auto childComponent = childItem->getComponent<T>();
 | 
			
		||||
          if(childComponent != nullptr) return childComponent;
 | 
			
		||||
          ++it;
 | 
			
		||||
        }
 | 
			
		||||
        return nullptr;
 | 
			
		||||
@@ -124,11 +156,16 @@ namespace Dawn {
 | 
			
		||||
       */
 | 
			
		||||
      template<class T>
 | 
			
		||||
      std::vector<std::shared_ptr<T>> findChildren() {
 | 
			
		||||
        auto it = this->transform.children.begin();
 | 
			
		||||
        auto it = this->children.begin();
 | 
			
		||||
        std::vector<std::shared_ptr<T>> children;
 | 
			
		||||
        while(it != this->transform.children.end()) {
 | 
			
		||||
          auto child = (*it)->item->getComponent<T>();
 | 
			
		||||
          if(child != nullptr) children.push_back(child);
 | 
			
		||||
        while(it != this->children.end()) {
 | 
			
		||||
          auto childItem = it->lock();
 | 
			
		||||
          if(childItem == nullptr) {
 | 
			
		||||
            ++it;
 | 
			
		||||
            continue;
 | 
			
		||||
          }
 | 
			
		||||
          auto childComponent = childItem->getComponent<T>();
 | 
			
		||||
          if(childComponent != nullptr) children.push_back(childComponent);
 | 
			
		||||
          ++it;
 | 
			
		||||
        }
 | 
			
		||||
        return children;
 | 
			
		||||
@@ -143,19 +180,146 @@ namespace Dawn {
 | 
			
		||||
       */
 | 
			
		||||
      template<class T>
 | 
			
		||||
      std::vector<std::shared_ptr<T>> findChildrenDeep() {
 | 
			
		||||
        std::vector<Transform*> transformsToCheck = this->transform.children;
 | 
			
		||||
        auto childrenToCheck = this->children;
 | 
			
		||||
        std::vector<std::shared_ptr<T>> itemsFound;
 | 
			
		||||
 | 
			
		||||
        while(transformsToCheck.size() > 0) {
 | 
			
		||||
          Transform *tras = *transformsToCheck.begin();
 | 
			
		||||
          vectorAppend(transformsToCheck, tras->children);
 | 
			
		||||
          auto component = tras->item->getComponent<T>();
 | 
			
		||||
        while(childrenToCheck.size() > 0) {
 | 
			
		||||
          auto it = *childrenToCheck.begin();
 | 
			
		||||
          auto otherItem = it.lock();
 | 
			
		||||
          if(otherItem != nullptr) {
 | 
			
		||||
            vectorAppend(childrenToCheck, otherItem->children);
 | 
			
		||||
          }
 | 
			
		||||
          auto component = otherItem->getComponent<T>();
 | 
			
		||||
          if(component != nullptr) itemsFound.push_back(component);
 | 
			
		||||
          transformsToCheck.erase(transformsToCheck.begin());
 | 
			
		||||
          childrenToCheck.erase(childrenToCheck.begin());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return itemsFound;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // // // // // // // // // // // // // // // // // // // // // // // // //
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * 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(const glm::vec3 position, const glm::vec3 look);
 | 
			
		||||
      void lookAt(
 | 
			
		||||
        const glm::vec3 position,
 | 
			
		||||
        const glm::vec3 look,
 | 
			
		||||
        const 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(
 | 
			
		||||
        const glm::vec3 position,
 | 
			
		||||
        const glm::vec3 look,
 | 
			
		||||
        const float_t viewportHeight,
 | 
			
		||||
        const 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(const 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(const 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(const 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(const 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(const 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(const std::shared_ptr<SceneItem> 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.
 | 
			
		||||
       */
 | 
			
		||||
      std::weak_ptr<SceneItem> 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(std::shared_ptr<SceneItem> p);
 | 
			
		||||
      
 | 
			
		||||
      /**
 | 
			
		||||
       * Destroy this SceneItem.
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ using namespace Dawn;
 | 
			
		||||
SceneItemComponent::SceneItemComponent(SceneItem *item) {
 | 
			
		||||
  assertNotNull(item, "SceneItemComponent::SceneItemComponent: Item cannot be null");
 | 
			
		||||
  this->item = item;
 | 
			
		||||
  this->transform = &item->transform;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItemComponent::init() {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
#include "display/Transform.hpp"
 | 
			
		||||
#include "scene/SceneItem.hpp"
 | 
			
		||||
#include "state/StateOwner.hpp"
 | 
			
		||||
 | 
			
		||||
@@ -15,7 +14,6 @@ namespace Dawn {
 | 
			
		||||
  class SceneItemComponent : public StateOwner {
 | 
			
		||||
    public:
 | 
			
		||||
      SceneItem *item;
 | 
			
		||||
      Transform *transform;
 | 
			
		||||
      bool_t hasInitialized = false;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,7 @@ glm::vec3 Camera::getRayDirectionFromScreenSpace(glm::vec2 screenSpace) {
 | 
			
		||||
  glm::vec4 eyeCoords = inverseProjectionMatrix * clipCoords;
 | 
			
		||||
  eyeCoords = glm::vec4(eyeCoords.x, eyeCoords.y, -1.0f, 0.0f);
 | 
			
		||||
 | 
			
		||||
  glm::mat4 inverseViewMatrix = glm::inverse(transform->getWorldTransform());
 | 
			
		||||
  glm::mat4 inverseViewMatrix = glm::inverse(item->getWorldTransform());
 | 
			
		||||
  glm::vec4 t = inverseViewMatrix * eyeCoords;
 | 
			
		||||
 | 
			
		||||
  return glm::normalize(glm::vec3(t.x, t.y, t.z));
 | 
			
		||||
 
 | 
			
		||||
@@ -33,13 +33,13 @@ void PixelPerfectCamera::updateDimensions() {
 | 
			
		||||
      break;
 | 
			
		||||
    
 | 
			
		||||
    case CAMERA_TYPE_PERSPECTIVE:
 | 
			
		||||
      this->transform->lookAtPixelPerfect(
 | 
			
		||||
      item->lookAtPixelPerfect(
 | 
			
		||||
        glm::vec3(0, 0, 0),
 | 
			
		||||
        glm::vec3(0, 0, 0),
 | 
			
		||||
        target->getHeight() / this->scale,
 | 
			
		||||
        this->camera->fov
 | 
			
		||||
      );
 | 
			
		||||
      // this->transform->lookAt(glm::vec3(360, 360, 360), glm::vec3(0, 0, 0));
 | 
			
		||||
      // this->lookAt(glm::vec3(360, 360, 360), glm::vec3(0, 0, 0));
 | 
			
		||||
      break;
 | 
			
		||||
    
 | 
			
		||||
    default:
 | 
			
		||||
 
 | 
			
		||||
@@ -29,10 +29,10 @@ ExampleSpin::ExampleSpin(SceneItem *item) :
 | 
			
		||||
 | 
			
		||||
void ExampleSpin::onStart() {
 | 
			
		||||
  useEvent([&](float_t delta){
 | 
			
		||||
    auto quat = this->transform->getLocalRotation();
 | 
			
		||||
    auto quat = item->getLocalRotation();
 | 
			
		||||
    quat = glm::rotate(quat, delta, glm::vec3(0, 1, 0));
 | 
			
		||||
    quat = glm::rotate(quat, delta / 2.0f, glm::vec3(1, 0, 0));
 | 
			
		||||
    quat = glm::rotate(quat, delta / 4.0f, glm::vec3(0, 0, 1));
 | 
			
		||||
    this->transform->setLocalRotation(quat);
 | 
			
		||||
    item->setLocalRotation(quat);
 | 
			
		||||
  }, getScene()->eventSceneUnpausedUpdate);
 | 
			
		||||
}
 | 
			
		||||
@@ -38,7 +38,7 @@ void CharacterController2D::onStart() {
 | 
			
		||||
      while(itColliders != allColliders.end()) {
 | 
			
		||||
        auto c = *itColliders;
 | 
			
		||||
        ++itColliders;
 | 
			
		||||
        if(c->item == this->item || c->transform->isChildOf(this->transform)) continue;
 | 
			
		||||
        if(c->item == this->item || c->item->isChildOf(item->shared_from_this())) continue;
 | 
			
		||||
        result = c->getCollidingResult(
 | 
			
		||||
          velocity,
 | 
			
		||||
          myCollider,
 | 
			
		||||
@@ -65,8 +65,8 @@ void CharacterController2D::onStart() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(moveAmount != glm::vec2(0, 0)) {
 | 
			
		||||
      transform->setLocalPosition(
 | 
			
		||||
        transform->getLocalPosition() + (glm::vec3(moveAmount.x, 0, moveAmount.y) * delta)
 | 
			
		||||
      item->setLocalPosition(
 | 
			
		||||
        item->getLocalPosition() + (glm::vec3(moveAmount.x, 0, moveAmount.y) * delta)
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -76,7 +76,7 @@ void CharacterController2D::onStart() {
 | 
			
		||||
    while(itTriggers != allTriggers.end()) {
 | 
			
		||||
      auto c = *itTriggers;
 | 
			
		||||
      ++itTriggers;
 | 
			
		||||
      if(c->item == this->item || c->transform->isChildOf(this->transform)) continue;
 | 
			
		||||
      if(c->item == this->item || c->item->isChildOf(item->shared_from_this())) continue;
 | 
			
		||||
      if(c->getCollidingResult(myCollider)) {
 | 
			
		||||
        c->eventTriggerEnter.invoke(this);
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ bool_t SolidController2D::getCollidingResult(
 | 
			
		||||
  assertNotNull(movingObject, "SolidController2D::getCollidingResult: Moving object cannot be null");
 | 
			
		||||
  if(movement.x == 0 && movement.y == 0) return false;
 | 
			
		||||
 | 
			
		||||
  auto myPos = physics3Dto2D(movingObject->transform->getWorldPosition());
 | 
			
		||||
  auto myPos = physics3Dto2D(movingObject->item->getWorldPosition());
 | 
			
		||||
 | 
			
		||||
  // Check what the moving object is
 | 
			
		||||
  switch(movingObject->getColliderType()) {
 | 
			
		||||
@@ -42,7 +42,7 @@ bool_t SolidController2D::getCollidingResult(
 | 
			
		||||
        case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
          auto box2 = std::static_pointer_cast<BoxCollider>(this->collider);
 | 
			
		||||
          assertNotNull(box2, "SolidController2D::getCollidingResult: Collider is not a BoxCollider");
 | 
			
		||||
          auto otherPos = physics3Dto2D(box2->transform->getWorldPosition());
 | 
			
		||||
          auto otherPos = physics3Dto2D(box2->item->getWorldPosition());
 | 
			
		||||
 | 
			
		||||
          return boxCheckCollision(
 | 
			
		||||
            myPos, box1->min, box1->max,
 | 
			
		||||
 
 | 
			
		||||
@@ -32,8 +32,8 @@ bool_t TriggerController2D::getCollidingResult(std::shared_ptr<Collider2D> movin
 | 
			
		||||
          auto box2 = std::static_pointer_cast<BoxCollider>(collider);
 | 
			
		||||
          assertNotNull(box2, "TriggerController2D::getCollidingResult: Collider is not a BoxCollider");
 | 
			
		||||
          return boxIsBoxColliding(
 | 
			
		||||
            physics3Dto2D(box1->transform->getWorldPosition()), box1->min, box1->max,
 | 
			
		||||
            physics3Dto2D(box2->transform->getWorldPosition()), box2->min, box2->max
 | 
			
		||||
            physics3Dto2D(box1->item->getWorldPosition()), box1->min, box1->max,
 | 
			
		||||
            physics3Dto2D(box2->item->getWorldPosition()), box2->min, box2->max
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ bool_t CapsuleCollider::performRaycast(
 | 
			
		||||
    {
 | 
			
		||||
      .height = this->height,
 | 
			
		||||
      .radius = this->radius,
 | 
			
		||||
      .origin = this->transform->getWorldPosition()
 | 
			
		||||
      .origin = item->getWorldPosition()
 | 
			
		||||
    },
 | 
			
		||||
    &result->point,
 | 
			
		||||
    &result->normal,
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,6 @@ void CharacterController3D::onStart() {
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // Move / Update
 | 
			
		||||
    transform->setLocalPosition(transform->getLocalPosition() + (velocity * delta));
 | 
			
		||||
    item->setLocalPosition(item->getLocalPosition() + (velocity * delta));
 | 
			
		||||
  }, getScene()->eventSceneUpdate);
 | 
			
		||||
}
 | 
			
		||||
@@ -20,7 +20,7 @@ bool_t CubeCollider::performRaycast(
 | 
			
		||||
  return Dawn::raytestCube(
 | 
			
		||||
    ray,
 | 
			
		||||
    { .min = this->min, .max = this->max },
 | 
			
		||||
    this->transform->getWorldTransform(),
 | 
			
		||||
    item->getWorldTransform(),
 | 
			
		||||
    &result->point,
 | 
			
		||||
    &result->normal,
 | 
			
		||||
    &result->distance
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ bool_t SphereCollider::performRaycast(
 | 
			
		||||
 | 
			
		||||
  return raytestSphere(
 | 
			
		||||
    ray,
 | 
			
		||||
    { .center = transform->getLocalPosition(), .radius = this->radius },
 | 
			
		||||
    { .center = item->getLocalPosition(), .radius = this->radius },
 | 
			
		||||
    &result->point,
 | 
			
		||||
    &result->normal,
 | 
			
		||||
    &result->distance
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ void SubSceneCameraAlign::realign() {
 | 
			
		||||
  float_t myRatio = this->camera->getAspect();
 | 
			
		||||
  
 | 
			
		||||
  this->camera->type = CAMERA_TYPE_ORTHONOGRAPHIC;
 | 
			
		||||
  this->camera->transform->lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0));
 | 
			
		||||
  this->camera->item->lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0));
 | 
			
		||||
 | 
			
		||||
  if(ratio > myRatio) {
 | 
			
		||||
    // My Ratio is narrower
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ std::vector<struct ShaderPassItem> UIBorder::getUIRenderPasses() {
 | 
			
		||||
  item.shader = shader;
 | 
			
		||||
  item.colorValues[shader->paramColor] = COLOR_WHITE;
 | 
			
		||||
  item.parameterBuffers[shader->bufferUiCanvas] = &this->getCanvas()->shaderBuffer;
 | 
			
		||||
  item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
 | 
			
		||||
  item.matrixValues[shader->paramModel] = this->item->getWorldTransform();
 | 
			
		||||
  if(this->texture == nullptr) {
 | 
			
		||||
    item.boolValues[shader->paramHasTexture] = false;
 | 
			
		||||
  } else {
 | 
			
		||||
@@ -45,7 +45,7 @@ std::vector<struct ShaderPassItem> UIBorder::getUIRenderPasses() {
 | 
			
		||||
    item.textureSlots[0] = this->texture;
 | 
			
		||||
    item.textureValues[shader->paramTexture] = 0;
 | 
			
		||||
  }
 | 
			
		||||
  item.w = this->transform->getWorldPosition().z;
 | 
			
		||||
  item.w = this->item->getWorldPosition().z;
 | 
			
		||||
  item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
 | 
			
		||||
  item.mesh = &mesh;
 | 
			
		||||
  
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ void UICanvas::rebufferShaderParameters() {
 | 
			
		||||
  switch(this->drawType) {
 | 
			
		||||
    case UI_DRAW_TYPE_WORLD_ABSOLUTE:
 | 
			
		||||
      data.projection = camera->getProjection();
 | 
			
		||||
      data.view = camera->transform->getWorldTransform();
 | 
			
		||||
      data.view = camera->item->getWorldTransform();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
 | 
			
		||||
 
 | 
			
		||||
@@ -22,9 +22,9 @@ UIComponent::UIComponent(SceneItem *item) :
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<UIComponentDimensional> UIComponent::getParentDimensional() {
 | 
			
		||||
  auto parent = this->transform->getParent();
 | 
			
		||||
  auto parent = item->getParent().lock();
 | 
			
		||||
  if(parent == nullptr) return nullptr;
 | 
			
		||||
  auto dimensional = parent->item->getComponent<UIComponentDimensional>();
 | 
			
		||||
  auto dimensional = parent->getComponent<UIComponentDimensional>();
 | 
			
		||||
  assertNotNull(dimensional, "UIComponent::getParentDimensional: Parent must have a UIComponentDimensional");
 | 
			
		||||
  return dimensional;
 | 
			
		||||
}
 | 
			
		||||
@@ -34,7 +34,7 @@ void UIComponent::updateAlignment() {
 | 
			
		||||
  
 | 
			
		||||
  auto align = (glm::vec4)this->alignment;
 | 
			
		||||
  auto dimensional = this->getParentDimensional();
 | 
			
		||||
  auto translate = this->transform->getLocalPosition();
 | 
			
		||||
  auto translate = item->getLocalPosition();
 | 
			
		||||
 | 
			
		||||
  assertNotNull(dimensional, "UIComponent::updateAlignment: Parent must have a UIComponentDimensional");
 | 
			
		||||
 | 
			
		||||
@@ -99,7 +99,7 @@ void UIComponent::updateAlignment() {
 | 
			
		||||
  translate.x += dimensional->getChildOffsetX();
 | 
			
		||||
  translate.y += dimensional->getChildOffsetY();
 | 
			
		||||
 | 
			
		||||
  this->transform->setLocalPosition(translate);
 | 
			
		||||
  item->setLocalPosition(translate);
 | 
			
		||||
  this->alignmentNeedsUpdating = false;
 | 
			
		||||
  this->eventAlignmentUpdated.invoke();
 | 
			
		||||
}
 | 
			
		||||
@@ -240,11 +240,11 @@ void UIComponent::calculateDimensions(
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<UICanvas> UIComponent::getCanvas() {
 | 
			
		||||
  // TODO: Cache this on first hit.
 | 
			
		||||
  auto parent = this->transform->getParent();
 | 
			
		||||
  while(parent != nullptr) {
 | 
			
		||||
    auto canvas = parent->item->getComponent<UICanvas>();
 | 
			
		||||
  auto parent = item->getParent().lock();
 | 
			
		||||
  while(parent) {
 | 
			
		||||
    auto canvas = parent->getComponent<UICanvas>();
 | 
			
		||||
    if(canvas != nullptr) return canvas;
 | 
			
		||||
    parent = parent->getParent();
 | 
			
		||||
    parent = parent->getParent().lock();
 | 
			
		||||
  }
 | 
			
		||||
  assertUnreachable("UIComponent::getCanvas: No canvas found");
 | 
			
		||||
  return nullptr;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ std::vector<struct ShaderPassItem> UIImage::getUIRenderPasses() {
 | 
			
		||||
  item.shader = shader;
 | 
			
		||||
  item.colorValues[shader->paramColor] = this->color;
 | 
			
		||||
  item.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer;
 | 
			
		||||
  item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
 | 
			
		||||
  item.matrixValues[shader->paramModel] = this->item->getWorldTransform();
 | 
			
		||||
  if(this->texture == nullptr) {
 | 
			
		||||
    item.boolValues[shader->paramHasTexture] = false;
 | 
			
		||||
  } else {
 | 
			
		||||
@@ -40,7 +40,7 @@ std::vector<struct ShaderPassItem> UIImage::getUIRenderPasses() {
 | 
			
		||||
    item.textureSlots[0] = this->texture;
 | 
			
		||||
    item.textureValues[shader->paramTexture] = 0;
 | 
			
		||||
  }
 | 
			
		||||
  item.w = this->transform->getWorldPosition().z;
 | 
			
		||||
  item.w = this->item->getWorldPosition().z;
 | 
			
		||||
  item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
 | 
			
		||||
  item.mesh = &mesh;
 | 
			
		||||
  return { item };
 | 
			
		||||
 
 | 
			
		||||
@@ -26,23 +26,23 @@ float_t UIMesh::getContentHeight() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<struct ShaderPassItem> UIMesh::getUIRenderPasses() {
 | 
			
		||||
  struct ShaderPassItem item;
 | 
			
		||||
  struct ShaderPassItem shaderItem;
 | 
			
		||||
  auto shader = getGame()->renderManager->uiShader;
 | 
			
		||||
  item.shader = shader;
 | 
			
		||||
  item.colorValues[shader->paramColor] = this->color;
 | 
			
		||||
  item.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer;
 | 
			
		||||
  item.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
 | 
			
		||||
  shaderItem.shader = shader;
 | 
			
		||||
  shaderItem.colorValues[shader->paramColor] = this->color;
 | 
			
		||||
  shaderItem.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer;
 | 
			
		||||
  shaderItem.matrixValues[shader->paramModel] = item->getWorldTransform();
 | 
			
		||||
  if(this->texture == nullptr) {
 | 
			
		||||
    item.boolValues[shader->paramHasTexture] = false;
 | 
			
		||||
    shaderItem.boolValues[shader->paramHasTexture] = false;
 | 
			
		||||
  } else {
 | 
			
		||||
    item.boolValues[shader->paramHasTexture] = true;
 | 
			
		||||
    item.textureSlots[0] = this->texture;
 | 
			
		||||
    item.textureValues[shader->paramTexture] = 0;
 | 
			
		||||
    shaderItem.boolValues[shader->paramHasTexture] = true;
 | 
			
		||||
    shaderItem.textureSlots[0] = this->texture;
 | 
			
		||||
    shaderItem.textureValues[shader->paramTexture] = 0;
 | 
			
		||||
  }
 | 
			
		||||
  item.w = this->transform->getWorldPosition().z;
 | 
			
		||||
  item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
 | 
			
		||||
  item.mesh = &mesh;
 | 
			
		||||
  return { item };
 | 
			
		||||
  shaderItem.w = item->getWorldPosition().z;
 | 
			
		||||
  shaderItem.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
 | 
			
		||||
  shaderItem.mesh = &mesh;
 | 
			
		||||
  return { shaderItem };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UIMesh::onStart() {
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ void UISimpleMenu::onStart() {
 | 
			
		||||
          case UI_DRAW_TYPE_WORLD_ABSOLUTE:
 | 
			
		||||
            mouse *= 2.0f;
 | 
			
		||||
            mouse -= glm::vec2(1, 1);
 | 
			
		||||
            ray.origin = canvas->camera->transform->getWorldPosition();
 | 
			
		||||
            ray.origin = canvas->camera->item->getWorldPosition();
 | 
			
		||||
            ray.direction = canvas->camera->getRayDirectionFromScreenSpace(mouse);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
@@ -107,7 +107,7 @@ void UISimpleMenu::onStart() {
 | 
			
		||||
          if(!raytestQuad(
 | 
			
		||||
            ray, 
 | 
			
		||||
            glm::vec2(0, 0), size,
 | 
			
		||||
            highlight->transform->getWorldTransform(),
 | 
			
		||||
            highlight->item->getWorldTransform(),
 | 
			
		||||
            &point,
 | 
			
		||||
            &normal,
 | 
			
		||||
            &distance
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@ std::vector<struct ShaderPassItem> UILabel::getUIRenderPasses() {
 | 
			
		||||
  auto shader = getGame()->renderManager->fontShader;
 | 
			
		||||
 | 
			
		||||
  // Translate
 | 
			
		||||
  glm::mat4 model = transform->getWorldTransform();
 | 
			
		||||
  glm::mat4 model = item->getWorldTransform();
 | 
			
		||||
  model = glm::translate(model, glm::vec3(this->textOffset, 0.0f));
 | 
			
		||||
 | 
			
		||||
  struct ShaderPassItem item;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user