Basic transform stuff
This commit is contained in:
@ -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>
|
||||
|
@ -7,6 +7,7 @@
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
RenderPipeline.cpp
|
||||
Transform.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
|
@ -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);
|
||||
|
156
src/dawn/display/Transform.cpp
Normal file
156
src/dawn/display/Transform.cpp
Normal 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;
|
||||
}
|
||||
}
|
69
src/dawn/display/Transform.hpp
Normal file
69
src/dawn/display/Transform.hpp
Normal 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();
|
||||
};
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
CubeMesh.cpp
|
||||
TriangleMesh.cpp
|
||||
QuadMesh.cpp
|
||||
)
|
64
src/dawn/display/mesh/CubeMesh.cpp
Normal file
64
src/dawn/display/mesh/CubeMesh.cpp
Normal 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
|
||||
}});
|
||||
}
|
21
src/dawn/display/mesh/CubeMesh.hpp
Normal file
21
src/dawn/display/mesh/CubeMesh.hpp
Normal 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
|
||||
);
|
||||
};
|
||||
}
|
@ -35,5 +35,5 @@ std::shared_ptr<SceneItem> Scene::createSceneItem() {
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
|
||||
std::cout << "What the dick" << std::endl;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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"
|
Reference in New Issue
Block a user