File GOPrimitive.cpp¶
File List > AIAC > GOSys > GOPrimitive.cpp
Go to the documentation of this file
// #####################################################################
// >>>>>>>>>>>>>>>>>>>>> BEGINNING OF LEGAL NOTICE >>>>>>>>>>>>>>>>>>>>>
//######################################################################
//
// This source file, along with its associated content, was authored by
// Andrea Settimi, Hong-Bin Yang, Naravich Chutisilp, and numerous other
// contributors. The code was originally developed at the Laboratory for
// Timber Construction (IBOIS, director: Prof. Yves Weinand) at the School of
// Architecture, Civil and Environmental Engineering (ENAC) at the Swiss
// Federal Institute of Technology in Lausanne (EPFL) for the Doctoral
// Research "Augmented Carpentry" (PhD researcher: Andrea Settimi,
// co-director: Dr. Julien Gamerro, director: Prof. Yves Weinand).
//
// Although the entire repository is distributed under the GPL license,
// these particular source files may also be used under the terms of the
// MIT license. By accessing or using this file, you agree to the following:
//
// 1. You may reproduce, modify, and distribute this file in accordance
// with the terms of the MIT license.
// 2. You must retain this legal notice in all copies or substantial
// portions of this file.
// 3. This file is provided "AS IS," without any express or implied
// warranties, including but not limited to the implied warranties of
// merchantability and fitness for a particular purpose.
//
// If you cannot or will not comply with the above conditions, you are
// not permitted to use this file. By proceeding, you acknowledge and
// accept all terms and conditions herein.
//
//######################################################################
// <<<<<<<<<<<<<<<<<<<<<<< END OF LEGAL NOTICE <<<<<<<<<<<<<<<<<<<<<<<<
// #####################################################################
//
#include "aiacpch.h"
#include "assimp/Importer.hpp" // C++ importer interface
#include "assimp/scene.h" // Output data structure
#include "assimp/postprocess.h" // Post processing flags
#include "glm/gtx/string_cast.hpp"
#include "AIAC/Log.h"
#include "AIAC/GOSys/GOPrimitive.h"
#include "AIAC/Application.h"
namespace AIAC
{
GOPrimitive::GOPrimitive(bool isVisible, glm::vec4 color)
: m_IsVisible(isVisible), m_Color(color), m_State(false)
{
m_Id = GenerateId();
}
uint32_t GOPrimitive::GenerateId()
{
uint32_t id = std::hash<std::string>{}(std::to_string(std::rand()));
if (AIAC_GOREG->CheckIfKeyExists(id))
return GenerateId();
else
return id;
}
// TODO: delete GL Objects
void GOPrimitive::Remove(const uint32_t& id)
{
AIAC_GOREG->GetGO<GOPrimitive>(id)->ClearGLObject();
AIAC_GOREG->Unregister(id);
}
void GOPrimitive::Remove(const std::shared_ptr<GOPrimitive>& ptrGO)
{
ptrGO->ClearGLObject();
AIAC_GOREG->Unregister(ptrGO->GetId());
}
void GOPrimitive::ClearGLObject()
{
for(auto& glObj : m_GLObjects)
glObj->DeleteVBOs();
m_GLObjects.clear();
}
GOPoint::GOPoint(float x, float y, float z, float weight)
{
m_Position = glm::vec3(x, y, z);
m_Type = GOTypeFlags::_GOPoint;
m_Weight = weight;
}
GOPoint::GOPoint(glm::vec3 position, float weight)
: m_Position(position)
{
m_Type = GOTypeFlags::_GOPoint;
m_Weight = weight;
}
std::shared_ptr<GOPoint> GOPoint::Add(float x, float y, float z, float weight)
{
auto ptrGO = std::make_shared<GOPoint>(GOPoint(x, y, z, weight));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOPoint> GOPoint::Add(glm::vec3 position, float weight)
{
auto ptrGO = std::make_shared<GOPoint>(GOPoint(position, weight));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
void GOPoint::InitGLObject()
{
ClearGLObject();
std::vector<glm::vec3> vertices;
std::vector<glm::vec4> colors;
vertices.push_back(m_Position);
colors.push_back(m_Color);
m_GLObjects.push_back(std::make_shared<GLPointObject>(vertices, colors, m_Weight));
}
std::shared_ptr<GOPoint> GOPoint::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOPoint>(id);
}
std::vector<std::shared_ptr<GOPoint>> GOPoint::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOPoint>();
}
GOLine::GOLine()
{
m_Type = GOTypeFlags::_GOLine;
}
GOLine::GOLine(GOPoint p1, GOPoint p2, float weight)
: m_PStart(p1), m_PEnd(p2)
{
m_Weight = weight;
m_Type = GOTypeFlags::_GOLine;
}
std::shared_ptr<GOLine> GOLine::Add()
{
auto ptrGO = std::make_shared<GOLine>(GOLine());
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOLine> GOLine::Add(GOPoint p1, GOPoint p2, float weight)
{
auto ptrGO = std::make_shared<GOLine>(GOLine(p1, p2, weight));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOLine> GOLine::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOLine>(id);
}
std::vector<std::shared_ptr<GOLine>> GOLine::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOLine>();
}
float GOLine::ComputeAngle(std::shared_ptr<GOLine> ptrGO2)
{
glm::vec3 v1 = this->m_PEnd.GetPosition() - this->m_PStart.GetPosition();
glm::vec3 v2 = ptrGO2->m_PEnd.GetPosition() - ptrGO2->m_PStart.GetPosition();
auto angle = glm::acos(glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2)));
return angle * 180.0f / glm::pi<float>();
}
float GOLine::ComputeSignedAngle(std::shared_ptr<GOLine> ptrGO2)
{
glm::vec3 v1 = this->m_PEnd.GetPosition() - this->m_PStart.GetPosition();
glm::vec3 v2 = ptrGO2->m_PEnd.GetPosition() - ptrGO2->m_PStart.GetPosition();
auto angle = glm::acos(glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2)));
auto cross = glm::cross(v1, v2);
if (cross.z < 0)
angle = -angle;
return angle * 180.0f / glm::pi<float>();
}
void GOLine::InitGLObject()
{
ClearGLObject();
std::vector<glm::vec3> vertices;
vertices.push_back(m_PStart.GetPosition());
vertices.push_back(m_PEnd.GetPosition());
m_GLObjects = CreatePolyline(vertices, false, m_Color, m_Weight);
}
GOCircle::GOCircle(GOPoint center, float radius)
: m_Center(center), m_Radius(radius)
{
m_Type = GOTypeFlags::_GOCircle;
}
GOCircle::GOCircle(GOPoint center, glm::vec3 normal, float radius)
: m_Center(center), m_Normal(normal), m_Radius(radius)
{
m_Type = GOTypeFlags::_GOCircle;
}
glm::vec3 GOCircle::ClosestPointToPoint(glm::vec3 point)
{
auto p1 = this->m_Center.GetPosition();
auto p2 = point;
auto v = p2 - p1;
auto mag = glm::length(v);
return p1 + (v / mag) * this->m_Radius;
}
void GOCircle::InitGLObject()
{
ClearGLObject();
m_GLObjects = CreateCircle(m_Center.GetPosition(), m_Normal, m_Radius, m_Color, m_Color, m_Weight);
}
std::shared_ptr<GOCircle> GOCircle::Add(GOPoint center, float radius)
{
auto ptrGO = std::make_shared<GOCircle>(GOCircle(center, radius));
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOCircle> GOCircle::Add(GOPoint center, glm::vec3 normal, float radius)
{
auto ptrGO = std::make_shared<GOCircle>(GOCircle(center, normal, radius));
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOCircle> GOCircle::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOCircle>(id);
}
std::vector<std::shared_ptr<GOCircle>> GOCircle::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOCircle>();
}
GOCylinder::GOCylinder(GOPoint p1, GOPoint p2, float radius)
: m_PStart(p1), m_PEnd(p2), m_Radius(radius)
{
m_Type = GOTypeFlags::_GOCylinder;
}
std::shared_ptr<GOCylinder> GOCylinder::Add(GOPoint p1, GOPoint p2, float radius)
{
auto ptrGO = std::make_shared<GOCylinder>(GOCylinder(p1, p2, radius));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
void GOCylinder::InitGLObject(){
ClearGLObject();
m_GLObjects = CreateCylinder(m_PStart.GetPosition(), m_PEnd.GetPosition(), m_Radius,
m_Color, m_Color);
}
std::shared_ptr<GOCylinder> GOCylinder::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOCylinder>(id);
}
std::vector<std::shared_ptr<GOCylinder>> GOCylinder::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOCylinder>();
}
GOPolyline::GOPolyline()
{
m_Type = GOTypeFlags::_GOPolyline;
}
GOPolyline::GOPolyline(std::vector<GOPoint> points, bool isClosed, float weight)
: m_Points(points), m_IsClosed(isClosed), m_Weight(weight)
{
m_Type = GOTypeFlags::_GOPolyline;
}
std::shared_ptr<GOPolyline> GOPolyline::Add()
{
auto ptrGO = std::make_shared<GOPolyline>(GOPolyline());
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOPolyline> GOPolyline::Add(std::vector<GOPoint> points, bool isClosed, float weight)
{
auto ptrGO = std::make_shared<GOPolyline>(GOPolyline(points, isClosed, weight));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOPolyline> GOPolyline::Add(std::vector<glm::vec3> points, bool isClosed, float weight)
{
// convert glm::vec3 to GOPoint
std::vector<GOPoint> pts;
for (auto& p : points) {
pts.push_back(GOPoint(p));
}
auto ptrGO = std::make_shared<GOPolyline>(GOPolyline(pts, isClosed, weight));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
void GOPolyline::InitGLObject() {
ClearGLObject();
vector<glm::vec3> vertices;
for (auto& p : m_Points) {
vertices.push_back(p.GetPosition());
}
m_GLObjects = CreatePolyline(vertices, m_IsClosed, m_Color, m_Weight);
}
std::shared_ptr<GOPolyline> GOPolyline::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOPolyline>(id);
}
std::vector<std::shared_ptr<GOPolyline>> GOPolyline::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOPolyline>();
}
GOTriangle::GOTriangle(GOPoint p1, GOPoint p2, GOPoint p3)
: m_P1(p1), m_P2(p2), m_P3(p3)
{
m_Type = GOTypeFlags::_GOTriangle;
}
void GOTriangle::InitGLObject() {
ClearGLObject();
std::vector<uint32_t> indices;
std::vector<glm::vec3> vertices;
std::vector<glm::vec4> colors;
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
vertices.push_back(m_P1.GetPosition());
vertices.push_back(m_P2.GetPosition());
vertices.push_back(m_P3.GetPosition());
colors.push_back(m_Color);
colors.push_back(m_Color);
colors.push_back(m_Color);
m_GLObjects.push_back(std::make_shared<GLMeshObject>(vertices, colors, indices));
}
std::shared_ptr<GOTriangle> GOTriangle::Add(GOPoint p1, GOPoint p2, GOPoint p3)
{
auto ptrGO = std::make_shared<GOTriangle>(GOTriangle(p1, p2, p3));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOTriangle> GOTriangle::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOTriangle>(id);
}
std::vector<std::shared_ptr<GOTriangle>> GOTriangle::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOTriangle>();
}
GOMesh::GOMesh()
{
m_Type = GOTypeFlags::_GOMesh;
}
GOMesh::GOMesh(std::vector<glm::vec3> vertices, std::vector<uint32_t> indices, std::vector<glm::vec3> normals, std::vector<glm::vec4> colors)
: m_Vertices(vertices), m_Indices(indices), m_Normals(normals), m_Colors(colors)
{
m_Type = GOTypeFlags::_GOMesh;
}
void GOMesh::InitGLObject(){
ClearGLObject();
if(m_Vertices.size() == 0){
return;
}
if(m_Indices.size() == 0){
return;
}
m_GLObjects.push_back(std::make_shared<GLMeshObject>(m_Vertices, m_Colors, m_Indices));
}
std::shared_ptr<GOMesh> GOMesh::Add()
{
auto ptrGO = std::make_shared<GOMesh>(GOMesh());
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOMesh> GOMesh::Add(std::vector<glm::vec3> vertices, std::vector<uint32_t> indices)
{
auto ptrGO = std::make_shared<GOMesh>(GOMesh(vertices, indices));
ptrGO->InitGLObject();
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOMesh> GOMesh::LoadPly(std::string path){
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(path, aiProcess_JoinIdenticalVertices);
if(!scene) {
AIAC_ERROR(importer.GetErrorString());
return nullptr;
}
const aiMesh* mesh = scene->mMeshes[0]; // TODO: here we use only the 1st mesh, make more?
auto ptrGO = std::make_shared<GOMesh>(GOMesh());
ptrGO->m_Vertices.reserve(mesh->mNumVertices);
for(unsigned int i=0; i<mesh->mNumVertices; i++){
aiVector3D pos = mesh->mVertices[i];
ptrGO->m_Vertices.emplace_back(pos.x, pos.y, pos.z);
}
ptrGO->m_Colors.reserve(mesh->mNumVertices);
for(unsigned int i=0; i<mesh->mNumVertices; i++){
ptrGO->m_Colors.emplace_back(0.5f, 0.3f, 0.1f, 1.0f);
}
ptrGO->m_Indices.reserve(mesh->mNumFaces * 3);
for(unsigned int i=0; i<mesh->mNumFaces; i++){
aiFace face = mesh->mFaces[i];
ptrGO->m_Indices.push_back(face.mIndices[0]);
ptrGO->m_Indices.push_back(face.mIndices[1]);
ptrGO->m_Indices.push_back(face.mIndices[2]);
}
ptrGO->InitGLObject();
// if(mesh->mNormals != nullptr){
// ptrGO->m_Normals.reserve(mesh->mNumVertices);
// for(unsigned int i=0; i<mesh->mNumVertices; i++){
// aiVector3D norm = mesh->mNormals[i];
// ptrGO->m_Normals.emplace_back(norm.x, norm.y, norm.z);
// }
// }
//
// if(mesh->mColors != nullptr){
// ptrGO->m_Colors.reserve(mesh->mNumVertices);
// for(unsigned int i=0; i<mesh->mNumVertices; i++){
// aiColor4D color = mesh->mColors[0][i];
// ptrGO->m_Colors.emplace_back(color.r, color.g, color.b, color.a);
// }
// }
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOMesh> GOMesh::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOMesh>(id);
}
std::vector<std::shared_ptr<GOMesh>> GOMesh::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOMesh>();
}
GOText::GOText()
{
m_Anchor.SetVisibility(false);
m_Type = GOTypeFlags::_GOText;
}
GOText::GOText(std::string text, GOPoint anchor, double size)
: m_Text(text), m_Anchor(anchor), m_Size(size)
{
m_Anchor.SetVisibility(false);
m_Type = GOTypeFlags::_GOText;
}
std::shared_ptr<GOText> GOText::Add()
{
auto ptrGO = std::make_shared<GOText>(GOText());
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOText> GOText::Add(std::string text, GOPoint anchor, double size)
{
auto ptrGO = std::make_shared<GOText>(GOText(text, anchor, size));
AIAC_GOREG->Register(ptrGO);
return ptrGO;
}
std::shared_ptr<GOText> GOText::Get(const uint32_t& id)
{
return AIAC_GOREG->GetGO<GOText>(id);
}
std::vector<std::shared_ptr<GOText>> GOText::GetAll()
{
return AIAC_GOREG->GetAllGOs<GOText>();
}
}