Nuked Transform

This commit is contained in:
2023-11-12 10:41:47 -06:00
parent 3ab98bf2ea
commit 31e922bb3e
34 changed files with 433 additions and 460 deletions

View File

@ -7,7 +7,6 @@
target_sources(${DAWN_TARGET_NAME} target_sources(${DAWN_TARGET_NAME}
PRIVATE PRIVATE
RenderPipeline.cpp RenderPipeline.cpp
Transform.cpp
Tileset.cpp Tileset.cpp
Color.cpp Color.cpp
) )

View File

@ -105,7 +105,7 @@ void RenderPipeline::renderSceneCamera(std::shared_ptr<Scene> scene, std::shared
// Update shader parameter buffers with current knowledge // Update shader parameter buffers with current knowledge
struct RenderPipelineShaderBufferData shaderBufferData; struct RenderPipelineShaderBufferData shaderBufferData;
shaderBufferData.projection = camera->getProjection(); shaderBufferData.projection = camera->getProjection();
shaderBufferData.view = camera->transform->getWorldTransform(); shaderBufferData.view = camera->item->getWorldTransform();
shaderBuffer.buffer(&shaderBufferData); shaderBuffer.buffer(&shaderBufferData);
// Prepare a render context. This is just a nice way of letting renderables // Prepare a render context. This is just a nice way of letting renderables

View File

@ -54,7 +54,10 @@ namespace Dawn {
* @param scene Scene to render. * @param scene Scene to render.
* @param camera Camera within the 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. * Cleanup a render pipeline that has been initialized.

View File

@ -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();
}
}

View File

@ -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;
};
}

View File

@ -32,7 +32,7 @@ namespace Dawn {
void onStart() override { void onStart() override {
assertNotNull(item); assertNotNull(item);
auto start = item->transform.getLocalPosition(); auto start = item->getLocalPosition();
if(from.x == VN_POSITION_EVENT_VALUE_UNCHANGED) start.x = from.x; if(from.x == VN_POSITION_EVENT_VALUE_UNCHANGED) start.x = from.x;
if(from.y == VN_POSITION_EVENT_VALUE_UNCHANGED) start.y = from.y; if(from.y == VN_POSITION_EVENT_VALUE_UNCHANGED) start.y = from.y;
if(from.z == VN_POSITION_EVENT_VALUE_UNCHANGED) start.z = from.z; if(from.z == VN_POSITION_EVENT_VALUE_UNCHANGED) start.z = from.z;
@ -45,7 +45,7 @@ namespace Dawn {
} }
void setValue(glm::vec3 value) override { void setValue(glm::vec3 value) override {
this->item->transform.setLocalPosition(value); this->item->setLocalPosition(value);
} }
}; };
} }

View File

@ -5,14 +5,19 @@
#include "SceneItem.hpp" #include "SceneItem.hpp"
#include "SceneItemComponent.hpp" #include "SceneItemComponent.hpp"
#include "util/mathutils.hpp"
using namespace Dawn; 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"); assertNotNull(scene, "SceneItem::SceneItem: Scene cannot be null");
this->id = id; this->id = id;
this->scene = scene; this->scene = scene;
this->updateLocalValuesFromLocalTransform();
} }
void SceneItem::init() { void SceneItem::init() {
@ -63,5 +68,185 @@ void SceneItem::destroy() {
this->components.clear(); 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() { 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();
}
} }

View File

@ -4,21 +4,47 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/Transform.hpp"
#include "scene/Scene.hpp" #include "scene/Scene.hpp"
#include "util/array.hpp" #include "util/array.hpp"
namespace Dawn { namespace Dawn {
class SceneItemComponent; class SceneItemComponent;
class SceneItem : public StateOwner { class SceneItem :
public StateOwner,
public std::enable_shared_from_this<SceneItem>
{
private: private:
std::vector<std::shared_ptr<SceneItemComponent>> components; 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: public:
Scene *scene; Scene *scene;
sceneitemid_t id; 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 * Constructor for a SceneItem. Scene Items should only be called and
@ -106,10 +132,16 @@ namespace Dawn {
*/ */
template<class T> template<class T>
std::shared_ptr<T> findChild() { std::shared_ptr<T> findChild() {
auto it = this->transform.children.begin(); auto it = this->children.begin();
while(it != this->transform.children.end()) { while(it != this->children.end()) {
auto child = (*it)->item->getComponent<T>(); auto childItem = it->lock();
if(child != nullptr) return child; if(childItem == nullptr) {
++it;
continue;
}
auto childComponent = childItem->getComponent<T>();
if(childComponent != nullptr) return childComponent;
++it; ++it;
} }
return nullptr; return nullptr;
@ -124,11 +156,16 @@ namespace Dawn {
*/ */
template<class T> template<class T>
std::vector<std::shared_ptr<T>> findChildren() { 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; std::vector<std::shared_ptr<T>> children;
while(it != this->transform.children.end()) { while(it != this->children.end()) {
auto child = (*it)->item->getComponent<T>(); auto childItem = it->lock();
if(child != nullptr) children.push_back(child); if(childItem == nullptr) {
++it;
continue;
}
auto childComponent = childItem->getComponent<T>();
if(childComponent != nullptr) children.push_back(childComponent);
++it; ++it;
} }
return children; return children;
@ -143,19 +180,146 @@ namespace Dawn {
*/ */
template<class T> template<class T>
std::vector<std::shared_ptr<T>> findChildrenDeep() { 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; std::vector<std::shared_ptr<T>> itemsFound;
while(transformsToCheck.size() > 0) { while(childrenToCheck.size() > 0) {
Transform *tras = *transformsToCheck.begin(); auto it = *childrenToCheck.begin();
vectorAppend(transformsToCheck, tras->children); auto otherItem = it.lock();
auto component = tras->item->getComponent<T>(); if(otherItem != nullptr) {
vectorAppend(childrenToCheck, otherItem->children);
}
auto component = otherItem->getComponent<T>();
if(component != nullptr) itemsFound.push_back(component); if(component != nullptr) itemsFound.push_back(component);
transformsToCheck.erase(transformsToCheck.begin()); childrenToCheck.erase(childrenToCheck.begin());
} }
return itemsFound; 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. * Destroy this SceneItem.

View File

@ -13,7 +13,6 @@ using namespace Dawn;
SceneItemComponent::SceneItemComponent(SceneItem *item) { SceneItemComponent::SceneItemComponent(SceneItem *item) {
assertNotNull(item, "SceneItemComponent::SceneItemComponent: Item cannot be null"); assertNotNull(item, "SceneItemComponent::SceneItemComponent: Item cannot be null");
this->item = item; this->item = item;
this->transform = &item->transform;
} }
void SceneItemComponent::init() { void SceneItemComponent::init() {

View File

@ -5,7 +5,6 @@
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "display/Transform.hpp"
#include "scene/SceneItem.hpp" #include "scene/SceneItem.hpp"
#include "state/StateOwner.hpp" #include "state/StateOwner.hpp"
@ -15,7 +14,6 @@ namespace Dawn {
class SceneItemComponent : public StateOwner { class SceneItemComponent : public StateOwner {
public: public:
SceneItem *item; SceneItem *item;
Transform *transform;
bool_t hasInitialized = false; bool_t hasInitialized = false;
/** /**

View File

@ -66,7 +66,7 @@ glm::vec3 Camera::getRayDirectionFromScreenSpace(glm::vec2 screenSpace) {
glm::vec4 eyeCoords = inverseProjectionMatrix * clipCoords; glm::vec4 eyeCoords = inverseProjectionMatrix * clipCoords;
eyeCoords = glm::vec4(eyeCoords.x, eyeCoords.y, -1.0f, 0.0f); 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; glm::vec4 t = inverseViewMatrix * eyeCoords;
return glm::normalize(glm::vec3(t.x, t.y, t.z)); return glm::normalize(glm::vec3(t.x, t.y, t.z));

View File

@ -33,13 +33,13 @@ void PixelPerfectCamera::updateDimensions() {
break; break;
case CAMERA_TYPE_PERSPECTIVE: case CAMERA_TYPE_PERSPECTIVE:
this->transform->lookAtPixelPerfect( item->lookAtPixelPerfect(
glm::vec3(0, 0, 0), glm::vec3(0, 0, 0),
glm::vec3(0, 0, 0), glm::vec3(0, 0, 0),
target->getHeight() / this->scale, target->getHeight() / this->scale,
this->camera->fov 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; break;
default: default:

View File

@ -29,10 +29,10 @@ ExampleSpin::ExampleSpin(SceneItem *item) :
void ExampleSpin::onStart() { void ExampleSpin::onStart() {
useEvent([&](float_t delta){ 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, glm::vec3(0, 1, 0));
quat = glm::rotate(quat, delta / 2.0f, glm::vec3(1, 0, 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)); quat = glm::rotate(quat, delta / 4.0f, glm::vec3(0, 0, 1));
this->transform->setLocalRotation(quat); item->setLocalRotation(quat);
}, getScene()->eventSceneUnpausedUpdate); }, getScene()->eventSceneUnpausedUpdate);
} }

View File

@ -38,7 +38,7 @@ void CharacterController2D::onStart() {
while(itColliders != allColliders.end()) { while(itColliders != allColliders.end()) {
auto c = *itColliders; auto c = *itColliders;
++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( result = c->getCollidingResult(
velocity, velocity,
myCollider, myCollider,
@ -65,8 +65,8 @@ void CharacterController2D::onStart() {
} }
if(moveAmount != glm::vec2(0, 0)) { if(moveAmount != glm::vec2(0, 0)) {
transform->setLocalPosition( item->setLocalPosition(
transform->getLocalPosition() + (glm::vec3(moveAmount.x, 0, moveAmount.y) * delta) item->getLocalPosition() + (glm::vec3(moveAmount.x, 0, moveAmount.y) * delta)
); );
} }
@ -76,7 +76,7 @@ void CharacterController2D::onStart() {
while(itTriggers != allTriggers.end()) { while(itTriggers != allTriggers.end()) {
auto c = *itTriggers; auto c = *itTriggers;
++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)) { if(c->getCollidingResult(myCollider)) {
c->eventTriggerEnter.invoke(this); c->eventTriggerEnter.invoke(this);
} }

View File

@ -29,7 +29,7 @@ bool_t SolidController2D::getCollidingResult(
assertNotNull(movingObject, "SolidController2D::getCollidingResult: Moving object cannot be null"); assertNotNull(movingObject, "SolidController2D::getCollidingResult: Moving object cannot be null");
if(movement.x == 0 && movement.y == 0) return false; 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 // Check what the moving object is
switch(movingObject->getColliderType()) { switch(movingObject->getColliderType()) {
@ -42,7 +42,7 @@ bool_t SolidController2D::getCollidingResult(
case COLLIDER2D_TYPE_BOX: { case COLLIDER2D_TYPE_BOX: {
auto box2 = std::static_pointer_cast<BoxCollider>(this->collider); auto box2 = std::static_pointer_cast<BoxCollider>(this->collider);
assertNotNull(box2, "SolidController2D::getCollidingResult: Collider is not a BoxCollider"); assertNotNull(box2, "SolidController2D::getCollidingResult: Collider is not a BoxCollider");
auto otherPos = physics3Dto2D(box2->transform->getWorldPosition()); auto otherPos = physics3Dto2D(box2->item->getWorldPosition());
return boxCheckCollision( return boxCheckCollision(
myPos, box1->min, box1->max, myPos, box1->min, box1->max,

View File

@ -32,8 +32,8 @@ bool_t TriggerController2D::getCollidingResult(std::shared_ptr<Collider2D> movin
auto box2 = std::static_pointer_cast<BoxCollider>(collider); auto box2 = std::static_pointer_cast<BoxCollider>(collider);
assertNotNull(box2, "TriggerController2D::getCollidingResult: Collider is not a BoxCollider"); assertNotNull(box2, "TriggerController2D::getCollidingResult: Collider is not a BoxCollider");
return boxIsBoxColliding( return boxIsBoxColliding(
physics3Dto2D(box1->transform->getWorldPosition()), box1->min, box1->max, physics3Dto2D(box1->item->getWorldPosition()), box1->min, box1->max,
physics3Dto2D(box2->transform->getWorldPosition()), box2->min, box2->max physics3Dto2D(box2->item->getWorldPosition()), box2->min, box2->max
); );
} }

View File

@ -22,7 +22,7 @@ bool_t CapsuleCollider::performRaycast(
{ {
.height = this->height, .height = this->height,
.radius = this->radius, .radius = this->radius,
.origin = this->transform->getWorldPosition() .origin = item->getWorldPosition()
}, },
&result->point, &result->point,
&result->normal, &result->normal,

View File

@ -30,6 +30,6 @@ void CharacterController3D::onStart() {
// } // }
// Move / Update // Move / Update
transform->setLocalPosition(transform->getLocalPosition() + (velocity * delta)); item->setLocalPosition(item->getLocalPosition() + (velocity * delta));
}, getScene()->eventSceneUpdate); }, getScene()->eventSceneUpdate);
} }

View File

@ -20,7 +20,7 @@ bool_t CubeCollider::performRaycast(
return Dawn::raytestCube( return Dawn::raytestCube(
ray, ray,
{ .min = this->min, .max = this->max }, { .min = this->min, .max = this->max },
this->transform->getWorldTransform(), item->getWorldTransform(),
&result->point, &result->point,
&result->normal, &result->normal,
&result->distance &result->distance

View File

@ -23,7 +23,7 @@ bool_t SphereCollider::performRaycast(
return raytestSphere( return raytestSphere(
ray, ray,
{ .center = transform->getLocalPosition(), .radius = this->radius }, { .center = item->getLocalPosition(), .radius = this->radius },
&result->point, &result->point,
&result->normal, &result->normal,
&result->distance &result->distance

View File

@ -23,7 +23,7 @@ void SubSceneCameraAlign::realign() {
float_t myRatio = this->camera->getAspect(); float_t myRatio = this->camera->getAspect();
this->camera->type = CAMERA_TYPE_ORTHONOGRAPHIC; 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) { if(ratio > myRatio) {
// My Ratio is narrower // My Ratio is narrower

View File

@ -37,7 +37,7 @@ std::vector<struct ShaderPassItem> UIBorder::getUIRenderPasses() {
item.shader = shader; item.shader = shader;
item.colorValues[shader->paramColor] = COLOR_WHITE; item.colorValues[shader->paramColor] = COLOR_WHITE;
item.parameterBuffers[shader->bufferUiCanvas] = &this->getCanvas()->shaderBuffer; 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) { if(this->texture == nullptr) {
item.boolValues[shader->paramHasTexture] = false; item.boolValues[shader->paramHasTexture] = false;
} else { } else {
@ -45,7 +45,7 @@ std::vector<struct ShaderPassItem> UIBorder::getUIRenderPasses() {
item.textureSlots[0] = this->texture; item.textureSlots[0] = this->texture;
item.textureValues[shader->paramTexture] = 0; 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.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
item.mesh = &mesh; item.mesh = &mesh;

View File

@ -26,7 +26,7 @@ void UICanvas::rebufferShaderParameters() {
switch(this->drawType) { switch(this->drawType) {
case UI_DRAW_TYPE_WORLD_ABSOLUTE: case UI_DRAW_TYPE_WORLD_ABSOLUTE:
data.projection = camera->getProjection(); data.projection = camera->getProjection();
data.view = camera->transform->getWorldTransform(); data.view = camera->item->getWorldTransform();
break; break;
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE: case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:

View File

@ -22,9 +22,9 @@ UIComponent::UIComponent(SceneItem *item) :
} }
std::shared_ptr<UIComponentDimensional> UIComponent::getParentDimensional() { std::shared_ptr<UIComponentDimensional> UIComponent::getParentDimensional() {
auto parent = this->transform->getParent(); auto parent = item->getParent().lock();
if(parent == nullptr) return nullptr; 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"); assertNotNull(dimensional, "UIComponent::getParentDimensional: Parent must have a UIComponentDimensional");
return dimensional; return dimensional;
} }
@ -34,7 +34,7 @@ void UIComponent::updateAlignment() {
auto align = (glm::vec4)this->alignment; auto align = (glm::vec4)this->alignment;
auto dimensional = this->getParentDimensional(); auto dimensional = this->getParentDimensional();
auto translate = this->transform->getLocalPosition(); auto translate = item->getLocalPosition();
assertNotNull(dimensional, "UIComponent::updateAlignment: Parent must have a UIComponentDimensional"); assertNotNull(dimensional, "UIComponent::updateAlignment: Parent must have a UIComponentDimensional");
@ -99,7 +99,7 @@ void UIComponent::updateAlignment() {
translate.x += dimensional->getChildOffsetX(); translate.x += dimensional->getChildOffsetX();
translate.y += dimensional->getChildOffsetY(); translate.y += dimensional->getChildOffsetY();
this->transform->setLocalPosition(translate); item->setLocalPosition(translate);
this->alignmentNeedsUpdating = false; this->alignmentNeedsUpdating = false;
this->eventAlignmentUpdated.invoke(); this->eventAlignmentUpdated.invoke();
} }
@ -240,11 +240,11 @@ void UIComponent::calculateDimensions(
std::shared_ptr<UICanvas> UIComponent::getCanvas() { std::shared_ptr<UICanvas> UIComponent::getCanvas() {
// TODO: Cache this on first hit. // TODO: Cache this on first hit.
auto parent = this->transform->getParent(); auto parent = item->getParent().lock();
while(parent != nullptr) { while(parent) {
auto canvas = parent->item->getComponent<UICanvas>(); auto canvas = parent->getComponent<UICanvas>();
if(canvas != nullptr) return canvas; if(canvas != nullptr) return canvas;
parent = parent->getParent(); parent = parent->getParent().lock();
} }
assertUnreachable("UIComponent::getCanvas: No canvas found"); assertUnreachable("UIComponent::getCanvas: No canvas found");
return nullptr; return nullptr;

View File

@ -32,7 +32,7 @@ std::vector<struct ShaderPassItem> UIImage::getUIRenderPasses() {
item.shader = shader; item.shader = shader;
item.colorValues[shader->paramColor] = this->color; item.colorValues[shader->paramColor] = this->color;
item.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer; item.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer;
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform(); item.matrixValues[shader->paramModel] = this->item->getWorldTransform();
if(this->texture == nullptr) { if(this->texture == nullptr) {
item.boolValues[shader->paramHasTexture] = false; item.boolValues[shader->paramHasTexture] = false;
} else { } else {
@ -40,7 +40,7 @@ std::vector<struct ShaderPassItem> UIImage::getUIRenderPasses() {
item.textureSlots[0] = this->texture; item.textureSlots[0] = this->texture;
item.textureValues[shader->paramTexture] = 0; 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.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
item.mesh = &mesh; item.mesh = &mesh;
return { item }; return { item };

View File

@ -26,23 +26,23 @@ float_t UIMesh::getContentHeight() {
} }
std::vector<struct ShaderPassItem> UIMesh::getUIRenderPasses() { std::vector<struct ShaderPassItem> UIMesh::getUIRenderPasses() {
struct ShaderPassItem item; struct ShaderPassItem shaderItem;
auto shader = getGame()->renderManager->uiShader; auto shader = getGame()->renderManager->uiShader;
item.shader = shader; shaderItem.shader = shader;
item.colorValues[shader->paramColor] = this->color; shaderItem.colorValues[shader->paramColor] = this->color;
item.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer; shaderItem.parameterBuffers[shader->bufferUiCanvas] = &getCanvas()->shaderBuffer;
item.matrixValues[shader->paramModel] = this->transform->getWorldTransform(); shaderItem.matrixValues[shader->paramModel] = item->getWorldTransform();
if(this->texture == nullptr) { if(this->texture == nullptr) {
item.boolValues[shader->paramHasTexture] = false; shaderItem.boolValues[shader->paramHasTexture] = false;
} else { } else {
item.boolValues[shader->paramHasTexture] = true; shaderItem.boolValues[shader->paramHasTexture] = true;
item.textureSlots[0] = this->texture; shaderItem.textureSlots[0] = this->texture;
item.textureValues[shader->paramTexture] = 0; shaderItem.textureValues[shader->paramTexture] = 0;
} }
item.w = this->transform->getWorldPosition().z; shaderItem.w = item->getWorldPosition().z;
item.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND; shaderItem.renderFlags = RENDER_MANAGER_RENDER_FLAG_BLEND;
item.mesh = &mesh; shaderItem.mesh = &mesh;
return { item }; return { shaderItem };
} }
void UIMesh::onStart() { void UIMesh::onStart() {

View File

@ -75,7 +75,7 @@ void UISimpleMenu::onStart() {
case UI_DRAW_TYPE_WORLD_ABSOLUTE: case UI_DRAW_TYPE_WORLD_ABSOLUTE:
mouse *= 2.0f; mouse *= 2.0f;
mouse -= glm::vec2(1, 1); mouse -= glm::vec2(1, 1);
ray.origin = canvas->camera->transform->getWorldPosition(); ray.origin = canvas->camera->item->getWorldPosition();
ray.direction = canvas->camera->getRayDirectionFromScreenSpace(mouse); ray.direction = canvas->camera->getRayDirectionFromScreenSpace(mouse);
break; break;
@ -107,7 +107,7 @@ void UISimpleMenu::onStart() {
if(!raytestQuad( if(!raytestQuad(
ray, ray,
glm::vec2(0, 0), size, glm::vec2(0, 0), size,
highlight->transform->getWorldTransform(), highlight->item->getWorldTransform(),
&point, &point,
&normal, &normal,
&distance &distance

View File

@ -90,7 +90,7 @@ std::vector<struct ShaderPassItem> UILabel::getUIRenderPasses() {
auto shader = getGame()->renderManager->fontShader; auto shader = getGame()->renderManager->fontShader;
// Translate // Translate
glm::mat4 model = transform->getWorldTransform(); glm::mat4 model = item->getWorldTransform();
model = glm::translate(model, glm::vec3(this->textOffset, 0.0f)); model = glm::translate(model, glm::vec3(this->textOffset, 0.0f));
struct ShaderPassItem item; struct ShaderPassItem item;

View File

@ -15,7 +15,7 @@ namespace Dawn {
void stage() override { void stage() override {
camera = Camera::create(this); camera = Camera::create(this);
camera->transform->lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0)); camera->lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0));
cube = SimpleSpinningCubePrefab::prefabCreate(this); cube = SimpleSpinningCubePrefab::prefabCreate(this);
} }

View File

@ -17,7 +17,7 @@ namespace Dawn {
void stage() override { void stage() override {
camera = Camera::create(this); camera = Camera::create(this);
camera->transform->lookAt(glm::vec3(3, 3, 3), glm::vec3(0, 0, 0)); camera->item->lookAt(glm::vec3(3, 3, 3), glm::vec3(0, 0, 0));
cube = SimpleSpinningCubePrefab::create(this); cube = SimpleSpinningCubePrefab::create(this);

View File

@ -17,17 +17,17 @@ void AudioListener::onStart() {
ALfloat listenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; ALfloat listenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 };
alListenerfv(AL_ORIENTATION, listenerOri); alListenerfv(AL_ORIENTATION, listenerOri);
glm::vec3 position = this->transform->getLocalPosition(); glm::vec3 position = this->item->getLocalPosition();
alListener3f(AL_POSITION, position.x, position.y, position.z); alListener3f(AL_POSITION, position.x, position.y, position.z);
this->transform->eventTransformUpdated.addListener(this, &AudioListener::onTransformUpdate); this->item->eventTransformUpdated.addListener(this, &AudioListener::onTransformUpdate);
} }
void AudioListener::onDispose() { void AudioListener::onDispose() {
this->transform->eventTransformUpdated.removeListener(this, &AudioListener::onTransformUpdate); this->item->eventTransformUpdated.removeListener(this, &AudioListener::onTransformUpdate);
} }
void AudioListener::onTransformUpdate() { void AudioListener::onTransformUpdate() {
glm::vec3 position = this->transform->getWorldPosition(); glm::vec3 position = this->item->getWorldPosition();
alListener3f(AL_POSITION, position.x, position.y, position.z); alListener3f(AL_POSITION, position.x, position.y, position.z);
} }

View File

@ -36,7 +36,7 @@ std::vector<struct ShaderPassItem>
onlyPass.mesh = mesh->mesh; onlyPass.mesh = mesh->mesh;
onlyPass.shader = shader; onlyPass.shader = shader;
onlyPass.colorValues[shader->paramColor] = this->color; onlyPass.colorValues[shader->paramColor] = this->color;
onlyPass.matrixValues[shader->paramModel] = this->transform->getWorldTransform(); onlyPass.matrixValues[shader->paramModel] = item->getWorldTransform();
onlyPass.parameterBuffers[shader->bufferRenderPipeline] = onlyPass.parameterBuffers[shader->bufferRenderPipeline] =
&context.renderPipeline->shaderBuffer &context.renderPipeline->shaderBuffer
; ;

View File

@ -38,7 +38,7 @@ std::vector<struct ShaderPassItem>
onlyPass.shader = shader; onlyPass.shader = shader;
onlyPass.colorValues[shader->paramColor] = this->color; onlyPass.colorValues[shader->paramColor] = this->color;
onlyPass.matrixValues[shader->paramModel] = onlyPass.matrixValues[shader->paramModel] =
this->transform->getWorldTransform() item->getWorldTransform()
; ;
onlyPass.parameterBuffers[ onlyPass.parameterBuffers[
shader->bufferRenderPipeline shader->bufferRenderPipeline

View File

@ -21,10 +21,10 @@ void GameCamera::onStart() {
assertNotNull(this->player); assertNotNull(this->player);
useEvent([&]{ useEvent([&]{
glm::vec3 lookOffset = player->transform->getLocalRotation() * glm::vec3(0, 0, 1.0f); glm::vec3 lookOffset = player->getLocalRotation() * glm::vec3(0, 0, 1.0f);
glm::vec2 target = glm::vec2(lookOffset.x, lookOffset.z) * lookOffsetScale; glm::vec2 target = glm::vec2(lookOffset.x, lookOffset.z) * lookOffsetScale;
slowTarget += (target - slowTarget) * getGame()->timeManager.delta * movementScrollSpeed; slowTarget += (target - slowTarget) * getGame()->timeManager.delta * movementScrollSpeed;
}, this->player->transform->eventTransformUpdated); }, this->player->eventTransformUpdated);
useEvent([&](float_t delta){ useEvent([&](float_t delta){
if(current != slowTarget) { if(current != slowTarget) {
@ -37,7 +37,7 @@ void GameCamera::onStart() {
} }
glm::vec3 current3 = glm::vec3(current.x, 0, current.y); glm::vec3 current3 = glm::vec3(current.x, 0, current.y);
glm::vec3 t0 = player->transform->getLocalPosition(); glm::vec3 t0 = player->getLocalPosition();
camera->transform->lookAt(t0 + current3 + zoomOffset, t0 + current3); camera->lookAt(t0 + current3 + zoomOffset, t0 + current3);
}, getScene()->eventSceneUpdate); }, getScene()->eventSceneUpdate);
} }