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

@ -37,6 +37,7 @@ extern "C" {
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/scalar_constants.hpp>

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

View File

@ -35,5 +35,5 @@ std::shared_ptr<SceneItem> Scene::createSceneItem() {
}
Scene::~Scene() {
std::cout << "What the dick" << std::endl;
}

View File

@ -11,10 +11,8 @@ using namespace Dawn;
SceneItem::SceneItem(Scene &scene, sceneitemid_t id) :
scene(scene),
id(id),
transform(1.0f)
transform(*this)
{
this->id = id;
this->transform = glm::translate(this->transform, glm::vec3(0, 0, 0));
}
void SceneItem::init() {
@ -22,5 +20,5 @@ void SceneItem::init() {
}
SceneItem::~SceneItem() {
std::cout << "Scene item disposed" << std::endl;
}

View File

@ -5,6 +5,7 @@
#pragma once
#include "SceneItemComponent.hpp"
#include "display/Transform.hpp"
namespace Dawn {
typedef int32_t sceneitemid_t;
@ -18,7 +19,7 @@ namespace Dawn {
public:
Scene &scene;
sceneitemid_t id;
glm::mat4 transform;
Transform transform;
/**
* Constructor for a SceneItem. Scene Items should only be called and

View File

@ -10,7 +10,10 @@
using namespace Dawn;
SceneItemComponent::SceneItemComponent(SceneItem &item) : item(item) {
SceneItemComponent::SceneItemComponent(SceneItem &item) :
item(item),
transform(item.transform)
{
}
Scene & SceneItemComponent::getScene() {

View File

@ -5,6 +5,7 @@
#pragma once
#include "dawnlibs.hpp"
#include "display/Transform.hpp"
namespace Dawn {
class SceneItem;
@ -14,6 +15,7 @@ namespace Dawn {
class SceneItemComponent {
public:
SceneItem &item;
Transform &transform;
/**
* Constructs a new SceneItemComponent. Components are attached to

View File

@ -41,14 +41,6 @@ void Camera::updateProjection() {
}
}
void Camera::lookAt(glm::vec3 pos, glm::vec3 look) {
this->lookAt(pos, look, glm::vec3(0, 1, 0));
}
void Camera::lookAt(glm::vec3 pos, glm::vec3 look, glm::vec3 up) {
this->item.transform = glm::lookAt(pos, look, up);
}
RenderTarget & Camera::getRenderTarget() {
if(this->target == nullptr) {
return this->getGame().renderManager.getBackBuffer();

View File

@ -48,9 +48,6 @@ namespace Dawn {
*/
void updateProjection();
void lookAt(glm::vec3 position, glm::vec3 look);
void lookAt(glm::vec3 position, glm::vec3 look, glm::vec3 up);
/**
* Returns the intended render target for this camera to render to, will
* automatically revert to the back buffer if no frame buffer is provided.

View File

@ -21,6 +21,14 @@ RenderManager::RenderManager(DawnGame &game) :
void RenderManager::init() {
this->standardRenderPipeline->init();
this->simpleShader->compile();
// Setup the alpha blend function.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
}
RenderTarget & RenderManager::getBackBuffer() {

View File

@ -7,6 +7,22 @@
using namespace Dawn;
std::shared_ptr<SceneItem> cubeCreate(std::shared_ptr<Scene> scene) {
auto cubeObject = scene->createSceneItem();
auto cubeMeshRenderer = cubeObject->addComponent<MeshRenderer>();
auto cubeMaterial = cubeObject->addComponent<Material>();
cubeMeshRenderer->mesh = std::make_shared<Mesh>();
cubeMeshRenderer->mesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
CubeMesh::buffer(
*cubeMeshRenderer->mesh,
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1, 1, 1),
0, 0
);
return cubeObject;
}
std::shared_ptr<SceneItem> cubeParent;
DawnGame::DawnGame(DawnHost &host) :
host(host),
renderManager(*this)
@ -21,22 +37,14 @@ int32_t DawnGame::init() {
auto cameraObject = this->scene->createSceneItem();
auto camera = cameraObject->addComponent<Camera>();
camera->lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0));
auto cubeObject = this->scene->createSceneItem();
auto cubeMeshRenderer = cubeObject->addComponent<MeshRenderer>();
auto cubeMaterial = cubeObject->addComponent<Material>();
cubeMeshRenderer->mesh = std::make_shared<Mesh>();
cubeMeshRenderer->mesh->createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
QuadMesh::bufferQuadMeshWithZ(
*cubeMeshRenderer->mesh,
glm::vec2(-1, -1), glm::vec2(0, 0),
glm::vec2(1, 1), glm::vec2(1, 1),
0, 0, 0
);
auto textureAsset = this->assetManager.load<TextureAsset>("texture_test");
cubeMaterial->textureValues[cubeMaterial->getShader()->getParameterByName("u_Text")] = std::shared_ptr<Texture>(textureAsset->texture);
camera->transform.lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0));
cubeParent = cubeCreate(this->scene);
auto cubeChild = cubeCreate(this->scene);
cubeChild->getComponent<Material>()->colorValues[cubeChild->getComponent<Material>()->getShader()->getParameterByName("u_Color")] = COLOR_MAGENTA;
cubeChild->transform.setParent(&cubeParent->transform);
cubeChild->transform.setLocalPosition(glm::vec3(1, 0, 0));
cubeParent->transform.setLocalPosition(glm::vec3(-0.5f, 0, 0));
return DAWN_GAME_INIT_RESULT_SUCCESS;
}
@ -45,6 +53,8 @@ int32_t DawnGame::update(float_t delta) {
this->assetManager.update();
if(this->scene != nullptr) this->scene->update();
cubeParent->transform.setLocalPosition(cubeParent->transform.getLocalPosition() + glm::vec3(-delta, 0, 0));
this->renderManager.update();

View File

@ -8,4 +8,5 @@
#include "scene/components/Components.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/mesh/TriangleMesh.hpp"
#include "display/mesh/CubeMesh.hpp"
#include "asset/assets/TextureAsset.hpp"