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