first release

This commit is contained in:
2019-10-14 23:02:51 +02:00
commit 542ef348ee
72 changed files with 5990 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
#pragma once
#include <glm/glm.hpp>
#include "../Base/IInitable.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
/**
* \brief A class that represents an axis aligned bounding box
*/
class AABB final : public virtual IInitable
{
glm::vec3 min, max;
public:
AABB() : min(INFINITY), max(-INFINITY) {}
~AABB() = default;
/**
* \brief Initiates the AABB to min=Inf, max=-Inf
*/
void Init() override
{
min = glm::vec3(INFINITY);
max = glm::vec3(-INFINITY);
}
/**
* \brief Initiates the AABB to a single point (min=max=point)
* \param point The point that should be used as min and max of the AABB
*/
void Init(const glm::vec3& point)
{
min = max = point;
}
/**
* \brief Initiates the AABB from some other AABB
* \param other The other AABB that should be copied
*/
void Init(const AABB& other)
{
min = other.GetMin();
max = other.GetMax();
}
const glm::vec3& GetMin() const { return min; }
const glm::vec3& GetMax() const { return max; }
void Grow(const glm::vec3& point)
{
min = glm::min(min, point);
max = glm::max(max, point);
}
void Grow(const AABB& otherAABB)
{
min = glm::min(min, otherAABB.GetMin());
max = glm::max(max, otherAABB.GetMax());
}
void Grow(const AABB& otherAABB, glm::mat4x4 transformation)
{
//TODO
}
glm::vec3 GetDiagonal() const
{
return max - min;
}
glm::vec3 GetCenter() const
{
return min + (GetDiagonal() * 0.5f);
}
/**
* \brief Checks if the AABB overlaps with an other AABB
* \param other The other AABB that should be checked
* \return true if the AABB overlaps with the other, false if not
*/
bool IsOverlapping(const AABB& other) const
{
return !(other.min.x > max.x || other.max.x < min.x || other.min.y > max.y || other.max.y < min.y || other.min.z > max.z || other.max.z < min.z);
}
/**
* \brief Resets the AABB to min=Inf, max=-Inf, same as Init()
*/
void Reset()
{
Init();
}
};
}
}

View File

@@ -0,0 +1,169 @@
#pragma once
#define _USE_MATH_DEFINES
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "Node.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
class Camera : public Node
{
protected:
float nearPlane, farPlane;
float width, height;
public:
glm::mat4x4 projection, view, viewProjection;
Camera() = default;
virtual ~Camera() = default;
public:
void Init(float width, float height, float nearPlane, float farPlane)
{
this->width = width;
this->height = height;
this->nearPlane = nearPlane;
this->farPlane = farPlane;
Node::Init();
UpdateProjectionMatrix();
}
virtual void SetSize(const float& width, const float& height)
{
this->width = width;
this->height = height;
UpdateProjectionMatrix();
}
void SetNearPlane(float nearPlane)
{
this->nearPlane = nearPlane;
}
void SetFarPlane(float farPlane)
{
this->farPlane = farPlane;
}
float NearPlane() const
{
return nearPlane;
}
float FarPlane() const
{
return farPlane;
}
virtual void UpdateProjectionMatrix() = 0;
void UpdateViewProjectionMatrix()
{ // In vulkan the screen space is defined as y=0=top and y=1=bottom and thus the coordinate have to be flipped
viewProjection = projection * glm::mat4x4(1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1) * view;
}
void UpdateWorldMatrix(const glm::mat4x4& parentWorldMat) override
{
Node::UpdateWorldMatrix(parentWorldMat);
view = glm::inverse(GetWorldMatrix());
UpdateViewProjectionMatrix();
}
const glm::mat4x4& GetViewProjectionMatrix() const
{
return viewProjection;
}
const glm::mat4x4* GetViewProjectionMatrixPointer() const
{
return &viewProjection;
}
};
class PerspectiveCamera : public Camera
{
protected:
float fov, aspect;
public:
void Init(float fovDegrees, float width, float height, float nearPlane, float farPlane)
{
this->fov = glm::radians(fovDegrees);
aspect = width / height;
Camera::Init(width, height, nearPlane, farPlane);
}
void SetSize(const float& width, const float& height) override
{
aspect = width / height;
Camera::SetSize(width, height);
}
void SetAspect(const float& aspect)
{
this->aspect = aspect;
Camera::SetSize(aspect, 1);
}
void SetFovX(const float& fov)
{
SetFov(2 * atan(tan(fov * 0.5f) * aspect));
}
void SetFovXRad(const float& fov)
{
SetFovRad(2 * atan(tan(fov * 0.5f) * aspect));
}
void SetFov(const float& fov)
{
SetFovRad(glm::radians(fov));
}
void SetFovRad(const float& fov)
{
this->fov = fov;
}
float GetFov() const
{
return glm::degrees(fov);
}
float GetFovX() const
{
return 2 * atan(tan(GetFov() * 0.5f) * aspect);
}
float GetFovRad() const
{
return fov;
}
float GetFovXRad() const
{
return 2 * atan(tan(fov * 0.5f) * aspect);
}
void UpdateProjectionMatrix() override
{
projection = glm::perspectiveLH_ZO(fov, aspect, nearPlane, farPlane);
UpdateViewProjectionMatrix();
}
};
class OrthographicCamera : public Camera
{
public:
void UpdateProjectionMatrix() override
{
const float widthHalf = width * 0.5f, heightHalf = height * 0.5f;
projection = glm::orthoLH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, nearPlane, farPlane);
UpdateViewProjectionMatrix();
}
};
}
}

View File

@@ -0,0 +1,26 @@
#include "Drawable.hpp"
#include "Scene.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
void Drawable::SetScene(Scene* scene)
{
if (this->scene == scene) return;
if (scene && this->scene) throw std::runtime_error("Drawable has been associated with a scene already!");
this->scene = scene;
if(scene) scene->RegisterDrawable(this);
}
void Drawable::RemoveNode(Node* node)
{
Utils::Remove(nodes, node);
if (nodes.empty())
{
scene = nullptr;
scene->RemoveDrawable(this);
}
}
}
}

View File

@@ -0,0 +1,82 @@
#pragma once
#include <vector>
#include "../Base/ICloseable.hpp"
#include "Geometry.hpp"
#include "Material.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
class Node;
class Scene;
struct Drawable : virtual public ICloseable
{
std::vector<Node*> nodes;
Scene* scene = nullptr;
Geometry* mesh = nullptr;
Material* material = nullptr;
public:
Drawable() = default;
explicit Drawable(const Drawable* toCopy)
{
mesh = toCopy->mesh;
material = toCopy->material;
}
virtual ~Drawable()
{
if(mesh) Drawable::Close();
}
Drawable* Copy() const
{
return new Drawable(this);
}
void Init(Geometry* mesh, Material* material)
{
if (this->mesh || this->material) throw std::runtime_error("Drawable is already initialized.");
this->mesh = mesh;
this->material = material;
}
void Init(Drawable* drawable)
{
if (mesh || material) throw std::runtime_error("Drawable is already initialized.");
this->mesh = drawable->mesh;
this->material = drawable->material;
}
void Close() override
{
if (!nodes.empty()) throw std::runtime_error("Drawable is still being used!!!");
mesh = nullptr;
material = nullptr;
}
Scene* GetScene() const
{
return scene;
}
private:
friend class Node;
friend class Scene;
void AddNode(Node* node)
{
if (!mesh) throw std::runtime_error("Drawable is not initialized.");
if (Utils::Contains(nodes, node)) throw std::runtime_error("A drawable must not use the same node more than once.");
nodes.push_back(node);
}
void SetScene(Scene* scene);
void RemoveNode(Node* node);
};
}
}

View File

@@ -0,0 +1,206 @@
#pragma once
#include <stdexcept>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include "Vertex.hpp"
#include "../Base/Logger.hpp"
#include "../Base/Utils.hpp"
#include "../Base/ICloseable.hpp"
#include "AABB.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
enum class VertexIndexType
{
UINT16 = sizeof(uint16_t), UINT32 = sizeof(uint32_t)
};
struct Geometry : public virtual ICloseable
{
uint32_t vertexCount = 0, indexCount = 0;
Vertex* vertices;
void* indices;
VertexIndexType indexType;
AABB aabb;
ICloseable* renderGeo = nullptr;
Vertex* GetVertices() const { return vertices; }
void* GetIndices() const { return indices; }
uint16_t* GetIndices16() const { return static_cast<uint16_t*>(indices); }
uint32_t* GetIndices32() const { return static_cast<uint32_t*>(indices); }
uint32_t GetIndexCount() const { return indexCount; }
uint32_t GetVertexCount() const { return vertexCount; }
static Geometry* LoadFromFile(const std::string file)
{
Geometry* mesh = new Geometry();
mesh->InitFromFile(file);
return mesh;
}
Geometry() : vertexCount(0), indexCount(0), vertices(nullptr), indices(nullptr), indexType(VertexIndexType::UINT16) {}
~Geometry()
{
if (vertices) Geometry::Close();
}
void InitFromFile(const std::string file)
{
Assimp::Importer importer;
const uint32_t flags = aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_GenNormals |
aiProcess_ImproveCacheLocality | aiProcess_RemoveRedundantMaterials | aiProcess_GenUVCoords | aiProcess_TransformUVCoords |
aiProcess_ConvertToLeftHanded | aiProcess_PreTransformVertices | aiProcess_OptimizeGraph;
const aiScene* scene = importer.ReadFile(file, flags);
if (!scene) throw std::runtime_error("Failed to load file \"" + file + "\" Error: " + importer.GetErrorString());
if (!scene->HasMeshes()) throw std::runtime_error("File \"" + file + "\" does not have any meshes");
if (scene->mNumMeshes > 1) Logger::DATA->warn("File {0} contains more than one mesh. Only first one will be loaded", file);
Init(scene->mMeshes[0]);
importer.FreeScene();
}
/**
* \brief Creates the arrays for the vertices and indices. They will not be filled!
* \param vertexCount The amount of vertices that will be used
* \param indexCount The amount of indices that will be used
*/
void Init(uint32_t vertexCount, uint32_t indexCount)
{
if (this->vertexCount || this->indexCount) throw std::runtime_error("Geometry is already initialized.");
this->vertexCount = vertexCount;
this->indexCount = indexCount;
indexType = (vertexCount > UINT16_MAX) ? VertexIndexType::UINT32 : VertexIndexType::UINT16;
vertices = new Vertex[vertexCount];
indices = malloc(static_cast<size_t>(Utils::EnumAsInt(indexType)) * indexCount);
renderGeo = nullptr;
}
void Init(aiMesh* mesh)
{
aabb.Init();
Init(mesh->mNumVertices, mesh->mNumFaces * 3); // Reserve the space for the data
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{
vertices[i].Set(mesh->mVertices[i]);
if (mesh->HasNormals()) vertices[i].SetNormal(mesh->mNormals[i]);
if (mesh->HasTangentsAndBitangents())
{
vertices[i].SetTangentAndBiTangent(mesh->mTangents[i], mesh->mBitangents[i]);
}
if (mesh->HasTextureCoords(0)) vertices[i].SetTextureCoordinates(mesh->mTextureCoords[0][i]);
if (mesh->HasVertexColors(0)) vertices[i].SetColor(mesh->mColors[0][i]);
aabb.Grow(vertices[i].position);
}
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
const aiFace face = mesh->mFaces[i];
if (face.mNumIndices != 3) throw std::runtime_error("Mesh is not a triangle mesh!");
for (unsigned int j = 0; j < face.mNumIndices; j++)
{
if (indexType == VertexIndexType::UINT16)
{
static_cast<uint16_t*>(indices)[i * face.mNumIndices + j] = static_cast<uint16_t>(face.mIndices[j]);
}
else
{
static_cast<uint32_t*>(indices)[i * face.mNumIndices + j] = face.mIndices[j];
}
}
}
//TODO load bones
//TODO load materials
}
void InitCube(float x = 1, float y = 1, float z = 1, glm::vec4 color = glm::vec4(1))
{
Init(24, 36);
SetIndices(new uint32_t[indexCount]{
0, 1, 2, 0, 2, 3, // front face index data
4, 5, 6, 4, 6, 7, // back face index data
8, 9, 10, 8, 10, 11, // top face index data
12, 13, 14, 12, 14, 15, // bottom face index data
16, 17, 18, 16, 18, 19, // left face index data
20, 21, 22, 20, 22, 23 // right face index data
}, indexCount);
x *= 0.5f; y *= 0.5f; z *= 0.5f;
int i = 0;
// front face vertex data
vertices[i++].Set(-x, +y, -z, +0, +0, -1, +0, +0);
vertices[i++].Set(-x, -y, -z, +0, +0, -1, +0, +1);
vertices[i++].Set(+x, -y, -z, +0, +0, -1, +1, +1);
vertices[i++].Set(+x, +y, -z, +0, +0, -1, +1, +0);
// back face vertex data
vertices[i++].Set(-x, +y, +z, +0, +0, +1, +1, +0);
vertices[i++].Set(+x, +y, +z, +0, +0, +1, +0, +0);
vertices[i++].Set(+x, -y, +z, +0, +0, +1, +0, +1);
vertices[i++].Set(-x, -y, +z, +0, +0, +1, +1, +1);
// top face vertex data
vertices[i++].Set(-x, -y, -z, +0, +1, +0, +0, +0);
vertices[i++].Set(-x, -y, +z, +0, +1, +0, +0, +1);
vertices[i++].Set(+x, -y, +z, +0, +1, +0, +1, +1);
vertices[i++].Set(+x, -y, -z, +0, +1, +0, +1, +0);
// bottom face vertex data
vertices[i++].Set(-x, +y, -z, +0, -1, +0, +1, +0);
vertices[i++].Set(+x, +y, -z, +0, -1, +0, +0, +0);
vertices[i++].Set(+x, +y, +z, +0, -1, +0, +0, +1);
vertices[i++].Set(-x, +y, +z, +0, -1, +0, +1, +1);
// Fill in the left face vertex data
vertices[i++].Set(-x, +y, +z, -1, +0, +0, +0, +0);
vertices[i++].Set(-x, -y, +z, -1, +0, +0, +0, +1);
vertices[i++].Set(-x, -y, -z, -1, +0, +0, +1, +1);
vertices[i++].Set(-x, +y, -z, -1, +0, +0, +1, +0);
// Fill in the right face vertex data
vertices[i++].Set(+x, +y, -z, +1, +0, +0, +0, +0);
vertices[i++].Set(+x, -y, -z, +1, +0, +0, +0, +1);
vertices[i++].Set(+x, -y, +z, +1, +0, +0, +1, +1);
vertices[i].Set(+x, +y, +z, +1, +0, +0, +1, +0);
for(i = 0; i < vertexCount; i++)
{
vertices[i].color = color;
}
}
void SetIndices(const uint32_t* data, uint32_t size, uint32_t offset = 0) const
{
size += offset;
for(; offset < size; offset++)
{
if (indexType == VertexIndexType::UINT16)
{
static_cast<uint16_t*>(indices)[offset] = static_cast<uint16_t>(data[offset]);
}
else
{
static_cast<uint32_t*>(indices)[offset] = data[offset];
}
}
}
void Close() override
{
vertexCount = 0;
indexCount = 0;
Free();
renderGeo->Close();
renderGeo = nullptr;
}
void Free()
{
if(vertices) delete[] vertices;
free(indices);
vertices = nullptr;
indices = nullptr;
}
};
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include "Shader.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
struct Material
{
Shader* shader;
};
}
}

View File

@@ -0,0 +1,9 @@
#include "Node.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
const glm::mat4x4 Node::IDENTITY = glm::mat4(1);
}
}

View File

@@ -0,0 +1,212 @@
#pragma once
#include <vector>
#include <stdexcept>
#include <glm/glm.hpp>
#include "../Base/Utils.hpp"
#include "../Base/IInitable.hpp"
#include "../Base/ICloseable.hpp"
#include "Drawable.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
class Scene;
enum class UpdateFrequency
{
Always, Sometimes, Never
};
struct Node : virtual IInitable, virtual ICloseable
{
friend Scene;
protected:
static const glm::mat4x4 IDENTITY;
public:
glm::mat4x4 localMat, worldMat;
bool enabled = true;
Node* parent = nullptr;
Scene* scene = nullptr;
std::vector<Node*> children;
std::vector<Drawable*> drawables;
UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never;
ICloseable* renderNode = nullptr;
public:
Node() = default;
virtual ~Node() = default;
void Init() override
{
if (parent || scene || !children.empty() || !drawables.empty()) throw std::runtime_error("Node already initialized");
localMat = worldMat = IDENTITY;
enabled = true;
parent = nullptr;
children = std::vector<Node*>();
drawables = std::vector<Drawable*>();
}
void Close() override
{
children.clear();
if (renderNode) renderNode->Close();
parent = nullptr;
scene = nullptr;
enabled = false;
if (!children.empty()) Logger::SCENE->warn("Closing Node that has children!");
for (Node* child : children)
{
child->SetParent(nullptr);
}
children.clear();
for(size_t i = drawables.size(); i > 0; i--)
{
RemoveDrawable(drawables[i]);
}
}
void AddChild(Node* node)
{
node->SetParent(this);
children.push_back(node);
node->UpdateWorldMatrix(worldMat);
}
void AddChild(Drawable* drawable)
{
AddDrawable(drawable);
}
void RemoveChild(Node* node)
{
if (node->parent == this)
{
Utils::Remove(children, node);
node->SetParent(nullptr);
}
}
void RemoveChild(Drawable* drawable)
{
RemoveDrawable(drawable);
}
void AddDrawable(Drawable* drawable)
{
if (scene) drawable->SetScene(scene);
else if (drawable->GetScene()) Logger::SCENE->warn("Drawable is already associated with a scene, but the node it was added to is not!");
drawable->AddNode(this);
drawables.push_back(drawable);
}
void RemoveDrawable(Drawable* drawable)
{
drawable->RemoveNode(this);
Utils::Remove(drawables, drawable);
}
void SetMatrix(glm::mat4x4 mat)
{
localMat = mat;
UpdateWorldMatrix(parent ? parent->GetWorldMatrix() : IDENTITY);
}
const glm::mat4x4& GetMatrix() const
{
return localMat;
}
const glm::mat4x4& GetWorldMatrix() const
{
return worldMat;
}
bool IsEnabled() const
{
return enabled;
}
void Enable()
{
enabled = true;
}
void Disable()
{
enabled = false;
}
Node* GetParent() const
{
return parent;
}
Scene* GetScene() const
{
return scene;
}
bool IsRoot() const
{
return scene && parent == this;
}
UpdateFrequency GetUpdateFrequency()
{
return matrixUpdateFrequency;
}
void SetUpdateFrequency(UpdateFrequency frequency)
{
if (!children.empty()) throw std::runtime_error("The update must not be changed for nodes with children.");
this->matrixUpdateFrequency = frequency;
}
protected:
virtual void UpdateWorldMatrix(const glm::mat4x4& parentWorldMat)
{
worldMat = parentWorldMat * localMat;
for (const auto& node : children)
{
node->UpdateWorldMatrix(worldMat);
}
}
private:
void SetParent(Node* parent)
{
if (this->parent && parent) throw std::runtime_error("Node already has a parent! Nodes must not be used multiple times!");
this->parent = parent;
if(parent && parent != this) this->scene = parent->scene;
if (!parent) SetScene(nullptr);
}
void SetScene(Scene* scene)
{
if (this->scene && scene) throw std::runtime_error("Node already has a scene!");
this->scene = scene;
for (const auto& node : children)
{
node->SetScene(scene);
}
if (scene)
{
for (size_t i = 0; i < drawables.size(); i++)
{
Scene* drawableScene = drawables[i]->GetScene();
if(drawableScene)
{
if(drawableScene != scene)
{
Logger::SCENE->warn("Drawable is already associated with a scene! Creating copy.");
drawables[i] = drawables[i]->Copy();
}
}
drawables[i]->SetScene(scene);
}
}
}
};
}
}

View File

@@ -0,0 +1,89 @@
#pragma once
#include "Node.hpp"
#include "Camera.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
struct Scene : virtual public IInitable, virtual public ICloseable
{
Node* root;
std::vector<Drawable*> shapeList;
Shader* shader;
Camera* camera;
public:
Scene() : root(nullptr) {}
virtual ~Scene()
{
if (root) Scene::Close();
}
void Init() override
{
Node* newRoot = new Node();
newRoot->Init();
Init(newRoot);
}
void Init(Node* root)
{
if (root->GetParent()) throw std::runtime_error("Node has a parent! Only nodes without a parent may be a root node!");
root->SetScene(this);
root->SetParent(root);
this->root = root;
}
void Close() override
{
//TODO
}
Node* GetRoot() const
{
return root;
}
void RegisterDrawable(Drawable* drawable)
{
if (drawable->GetScene() != this) drawable->SetScene(this);
if (Utils::Contains(shapeList, drawable)) return; // Prevent duplicate entries
shapeList.push_back(drawable);
}
void RemoveDrawable(Drawable* drawable)
{
Utils::Remove(shapeList, drawable);
drawable->SetScene(nullptr);
}
void SetCamera(Camera* camera)
{
this->camera = camera;
}
Camera* GetCamera() const
{
return camera;
}
/**
* \brief Checks if the scene is valid and attempts to fix problems.
*/
void Validate()
{
for (Drawable* drawable : shapeList)
{
if(drawable->GetScene() != this)
{
if (!drawable->GetScene()) drawable->SetScene(this);
else Logger::SCENE->error("Scene is linked with drawable from different scene!!!"); //TODO handle
}
}
//TODO check node tree
}
};
}
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include <string>
#include <stdexcept>
#include "../Base/ICloseable.hpp"
namespace openVulkanoCpp
{
namespace Scene
{
enum class Topology
{
PointList, LineList, LineStripe, TriangleList, TriangleStripe
};
struct Shader : public virtual ICloseable
{
std::string vertexShaderName, fragmentShaderName;
Topology topology = Topology::TriangleList;
ICloseable* renderShader = nullptr;
Shader() = default;
~Shader() { if (renderShader) Shader::Close(); }
void Init(const std::string& vertexShaderName, const std::string& fragmentShaderName)
{
if (renderShader) throw std::runtime_error("Shader already initialized!");
this->vertexShaderName = vertexShaderName;
this->fragmentShaderName = fragmentShaderName;
}
void Close() override
{
renderShader->Close();
renderShader = nullptr;
}
};
}
}

View File

@@ -0,0 +1,178 @@
#pragma once
#include <glm/glm.hpp>
#include <assimp/vector2.h>
#include <assimp/vector3.h>
namespace openVulkanoCpp
{
struct Vertex
{
glm::vec3 position, normal, tangent, biTangent, textureCoordinates;
glm::vec4 color;
Vertex() = default;
Vertex(const aiVector3D& pos) : position(pos.x, pos.y, pos.z), normal(), tangent(), biTangent(), textureCoordinates(), color()
{}
Vertex(const float& x, const float& y, const float& z, const float& nx, const float& ny, const float& nz, const float& u, const float& v)
: position({ x, y, z }), normal({ nx, ny, nz }), tangent(), biTangent(), textureCoordinates({ u, v, 0 }), color()
{}
Vertex(const glm::vec3& position, const glm::vec3& normal, const glm::vec3& tangent, const glm::vec3& biTangent, const glm::vec2& textureCoordinates)
: position(position), normal(normal), tangent(tangent), biTangent(biTangent), textureCoordinates(textureCoordinates, 0), color()
{}
Vertex(const glm::vec3 & position, const glm::vec3 & normal, const glm::vec3 & tangent, const glm::vec3 & biTangent, const glm::vec3 & textureCoordinates)
: position(position), normal(normal), tangent(tangent), biTangent(biTangent), textureCoordinates(textureCoordinates), color()
{}
~Vertex() = default;
void Set(const float& x, const float& y, const float& z)
{
position = { x, y, z };
}
void Set(const glm::vec3& position)
{
this->position = position;
}
void Set(const aiVector3D& position)
{
this->position = { position.x, position.y, position.z };
}
void Set(const float& x, const float& y, const float& z, const float& nx, const float& ny, const float& nz, const float& u, const float& v)
{
this->position = { x, y, z };
this->normal = { nx, ny, nz };
this->textureCoordinates = { u, v, 0 };
}
void Set(const glm::vec3& position, const glm::vec3& normal, const glm::vec2& textureCoordinates)
{
this->position = position;
this->normal = normal;
this->textureCoordinates = { textureCoordinates, 0 };
}
void Set(const glm::vec3& position, const glm::vec3& normal, const glm::vec3& tangent, const glm::vec3& biTangent, const glm::vec2& textureCoordinates)
{
this->position = position;
this->normal = normal;
this->tangent = tangent;
this->biTangent = biTangent;
this->textureCoordinates = { textureCoordinates,0 };
}
void SetNormal(const float& nx, const float& ny, const float& nz)
{
this->normal = { nx, ny, nz };
}
void SetNormal(const glm::vec3& normal)
{
this->normal = normal;
}
void SetNormal(const aiVector3D& normal)
{
this->normal = { normal.x, normal.y, normal.z };
}
void SetTangent(const float& tx, const float& ty, const float& tz)
{
this->tangent = { tx, ty, tz };
}
void SetTangent(const glm::vec3& tangent)
{
this->tangent = tangent;
}
void SetTangent(const aiVector3D& tangent)
{
this->tangent = { tangent.x, tangent.y, tangent.z };
}
void SetTangentAndBiTangent(const float& tx, const float& ty, const float& tz, const float& bx, const float& by, const float& bz)
{
this->biTangent = { bx, by, bz };
this->tangent = { tx, ty, tz };
}
void SetTangentAndBiTangent(const glm::vec3& tangent, const glm::vec3& biTangent)
{
this->biTangent = biTangent;
this->tangent = tangent;
}
void SetTangentAndBiTangent(const aiVector3D& tangent, const aiVector3D& biTangent)
{
this->tangent = { tangent.x, tangent.y, tangent.z };
this->biTangent = { biTangent.x, biTangent.y, biTangent.z };
}
void SetBiTangent(const float& bx, const float& by, const float& bz)
{
this->biTangent = { bx, by, bz };
}
void SetBiTangent(const glm::vec3& biTangent)
{
this->biTangent = biTangent;
}
void SetBiTangent(const aiVector3D& biTangent)
{
this->biTangent = { biTangent.x, biTangent.y, biTangent.z };
}
void SetTextureCoordinates(const float& u, const float& v)
{
this->textureCoordinates = { u, v, 0 };
}
void SetTextureCoordinates(const float& u, const float& v, const float& w)
{
this->textureCoordinates = { u, v, w };
}
void SetTextureCoordinates(const glm::vec2& textureCoordinates)
{
this->textureCoordinates = { textureCoordinates, 0 };
}
void SetTextureCoordinates(const glm::vec3& textureCoordinates)
{
this->textureCoordinates = textureCoordinates;
}
void SetTextureCoordinates(const aiVector2D& textureCoordinates)
{
this->textureCoordinates = { textureCoordinates.x, textureCoordinates.y, 0 };
}
void SetTextureCoordinates(const aiVector3D& textureCoordinates)
{
this->textureCoordinates = { textureCoordinates.x, textureCoordinates.y, textureCoordinates.z };
}
void SetColor(const float& r, const float& g, const float& b, const float& a = 1)
{
color = { r,g,b,a };
}
void SetColor(const glm::vec4& color)
{
this->color = color;
}
void SetColor(const aiColor4D& color)
{
this->color = { color.r, color.g, color.b, color.a };
}
};
}