Basic transform stuff

This commit is contained in:
2022-10-21 22:01:37 -07:00
parent 043873cc2d
commit be529b70c1
18 changed files with 363 additions and 38 deletions

View File

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

View File

@ -58,18 +58,18 @@ void RenderPipeline::renderSceneCamera(Scene &scene, Camera &camera) {
auto it = meshes.begin();
while(it != meshes.end()) {
auto mesh = *it;
auto item = mesh->item;
auto material = item.getComponent<Material>();
auto material = mesh->item.getComponent<Material>();
// TODO: fallback material?
if(material == nullptr) {
++it;
continue;
}
auto shader = material->getShader();
shader->bind();
shader->setGlobalParameters(camera.projection, camera.item.transform);
shader->setMeshParameters(item.transform);
shader->setGlobalParameters(camera.projection, camera.transform.getWorldTransform());
shader->setMeshParameters(mesh->item.transform.getWorldTransform());
material->setShaderParameters();
mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);

View File

@ -0,0 +1,156 @@
// 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"
using namespace Dawn;
Transform::Transform(SceneItem &item) :
item(item),
transformLocal(1.0f),
transformWorld(1.0f)
{
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() {
glm::mat4 newWorld(1.0f);
auto parent = this->getParent();
if(parent != nullptr) newWorld = parent->getWorldTransform();
this->transformWorld = newWorld * 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));
}
glm::vec3 Transform::getLocalPosition() {
return this->localPosition;
}
void Transform::setLocalPosition(glm::vec3 position) {
this->localPosition = position;
this->updateLocalTransformFromLocalValues();
this->updateChildrenTransforms();
}
glm::vec3 Transform::getLocalScale() {
return this->scale;
}
void Transform::setLocalScale(glm::vec3 scale) {
this->localScale = scale;
this->updateLocalTransformFromLocalValues();
this->updateChildrenTransforms();
}
glm::quat Transform::getLocalRotation() {
return this->localRotation;
}
void Transform::setLocalRotation(glm::quat rotation) {
this->localRotation = rotation;
this->updateLocalTransformFromLocalValues();
this->updateChildrenTransforms();
}
glm::mat4 Transform::getLocalTransform() {
return this->transformLocal;
}
void Transform::setLocalTransform(glm::mat4 transform) {
this->transformLocal = transform;
this->updateLocalValuesFromLocalTransform();
this->updateChildrenTransforms();
}
glm::mat4 Transform::getWorldTransform() {
return this->transformWorld;
}
void Transform::setWorldTransform(glm::mat4 transform) {
this->transformWorld = transform;
this->updateLocalTransformFromWorldTransform();
this->updateChildrenTransforms();
}
void Transform::setParent(Transform *parent) {
if(parent == this) throw "Cannot self reference";
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);
}
Transform * Transform::getParent() {
return this->parent;
}
Transform::~Transform() {
this->setParent(nullptr);
auto it = this->parent->children.begin();
while(it != this->parent->children.end()) {
(*it)->setParent(nullptr);
++it;
}
}

View File

@ -0,0 +1,69 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
#include "util/flag.hpp"
namespace Dawn {
class SceneItem;
class Transform : public std::enable_shared_from_this<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:
SceneItem &item;
Transform(SceneItem &item);
void lookAt(glm::vec3 position, glm::vec3 look);
void lookAt(glm::vec3 position, glm::vec3 look, glm::vec3 up);
glm::vec3 getLocalPosition();
void setLocalPosition(glm::vec3 position);
glm::vec3 getLocalScale();
void setLocalScale(glm::vec3 scale);
glm::quat getLocalRotation();
void setLocalRotation(glm::quat rotation);
glm::mat4 getLocalTransform();
void setLocalTransform(glm::mat4 transform);
glm::mat4 getWorldTransform();
void setWorldTransform(glm::mat4 transform);
void setParent(Transform *p);
Transform * getParent();
~Transform();
};
}

View File

@ -6,6 +6,7 @@
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
CubeMesh.cpp
TriangleMesh.cpp
QuadMesh.cpp
)

View File

@ -0,0 +1,64 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "CubeMesh.hpp"
using namespace Dawn;
void CubeMesh::buffer(
Mesh &mesh,
glm::vec3 pos, glm::vec3 size,
int32_t verticeStart, int32_t indiceStart
) {
mesh.bufferPositions(verticeStart, std::array<glm::vec3, CUBE_VERTICE_COUNT>{{
pos,
glm::vec3(pos.x+size.x, pos.y, pos.z),
glm::vec3(pos.x, pos.y+size.y, pos.z),
glm::vec3(pos.x+size.x, pos.y+size.y, pos.z),
glm::vec3(pos.x, pos.y, pos.z+size.z),
glm::vec3(pos.x+size.x, pos.y, pos.z+size.z),
glm::vec3(pos.x, pos.y+size.y, pos.z+size.z),
pos + size
}});
mesh.bufferCoordinates(verticeStart,std::array<glm::vec2,CUBE_VERTICE_COUNT>{{
glm::vec2(0, 0),
glm::vec2(1, 0),
glm::vec2(0, 1),
glm::vec2(1, 1),
glm::vec2(0, 0),
glm::vec2(1, 0),
glm::vec2(0, 1),
glm::vec2(1, 1)
}});
mesh.bufferIndices(indiceStart, std::array<meshindice_t, CUBE_INDICE_COUNT>{{
// Back
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3,
// Right
verticeStart + 1, verticeStart + 5, verticeStart + 7,
verticeStart + 1, verticeStart + 3, verticeStart + 7,
// Left
verticeStart + 4, verticeStart, verticeStart + 2,
verticeStart + 4, verticeStart + 6, verticeStart + 2,
// Front
verticeStart + 5, verticeStart + 4, verticeStart + 6,
verticeStart + 5, verticeStart + 7, verticeStart + 6,
// Top
verticeStart + 7, verticeStart + 2, verticeStart + 6,
verticeStart + 7, verticeStart + 3, verticeStart + 2,
// Bottom
verticeStart + 1, verticeStart, verticeStart + 4,
verticeStart + 1, verticeStart + 4, verticeStart + 5
}});
}

View File

@ -0,0 +1,21 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#define CUBE_VERTICE_COUNT 8
#define CUBE_INDICE_COUNT 36
namespace Dawn {
class CubeMesh {
public:
static void buffer(
Mesh &mesh,
glm::vec3 pos, glm::vec3 size,
int32_t verticeStart, int32_t indiceStart
);
};
}