2021-09-13 15:53:43 +03:00
|
|
|
//
|
|
|
|
// Created by Иван Ильин on 13.01.2021.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include <utility>
|
2021-10-31 11:39:08 +03:00
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
#include "Mesh.h"
|
2021-10-18 06:44:04 +03:00
|
|
|
#include "ResourceManager.h"
|
2021-11-05 23:55:42 +03:00
|
|
|
#include "Screen.h"
|
2021-09-13 15:53:43 +03:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
Mesh &Mesh::operator*=(const Matrix4x4 &matrix4X4) {
|
2021-10-12 17:12:47 +03:00
|
|
|
std::vector<Triangle> newTriangles;
|
2021-11-04 03:44:53 +03:00
|
|
|
newTriangles.reserve(_tris.size());
|
2021-10-31 11:39:08 +03:00
|
|
|
for (auto &t : _tris) {
|
2021-10-12 17:12:47 +03:00
|
|
|
newTriangles.emplace_back(t * matrix4X4);
|
|
|
|
}
|
2021-11-04 03:44:53 +03:00
|
|
|
setTriangles(std::move(newTriangles));
|
2021-09-13 15:53:43 +03:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
void Mesh::loadObj(const std::string &filename, const Vec3D &scale) {
|
2021-11-06 22:11:06 +03:00
|
|
|
_tris.clear();
|
2021-10-18 09:21:09 +03:00
|
|
|
auto objects = ResourceManager::loadObjects(filename);
|
2021-10-31 11:39:08 +03:00
|
|
|
for (auto &obj : objects) {
|
2021-09-13 15:53:43 +03:00
|
|
|
for (auto &tri : obj->triangles()) {
|
2021-09-19 11:25:10 +03:00
|
|
|
_tris.push_back(tri);
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
}
|
2021-10-18 09:21:09 +03:00
|
|
|
this->scale(scale);
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
Mesh::Mesh(ObjectNameTag nameTag, const std::string &filename, const Vec3D &scale) : Object(std::move(nameTag)) {
|
2021-10-17 20:52:21 +03:00
|
|
|
loadObj(filename, scale);
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-29 23:44:37 +03:00
|
|
|
Mesh::Mesh(ObjectNameTag nameTag, const vector<Triangle> &tries) : Object(std::move(nameTag)), _tris(tries) {
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
Mesh Mesh::Obj(ObjectNameTag nameTag, const std::string &filename) {
|
2021-10-28 16:58:02 +03:00
|
|
|
return Mesh(std::move(nameTag), filename);
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
void Mesh::setColor(const sf::Color &c) {
|
2021-09-19 11:25:10 +03:00
|
|
|
_color = c;
|
2021-10-12 17:12:47 +03:00
|
|
|
|
|
|
|
// change color of all mesh triangles:
|
|
|
|
std::vector<Triangle> newTriangles;
|
2021-11-04 03:44:53 +03:00
|
|
|
newTriangles.reserve(_tris.size());
|
2021-10-31 11:39:08 +03:00
|
|
|
for (auto &t : _tris) {
|
2021-10-12 17:12:47 +03:00
|
|
|
newTriangles.emplace_back(Triangle(t[0], t[1], t[2], c));
|
|
|
|
}
|
2021-11-04 03:44:53 +03:00
|
|
|
setTriangles(std::move(newTriangles));
|
2021-09-13 15:53:43 +03:00
|
|
|
}
|
|
|
|
|
2021-10-31 11:39:08 +03:00
|
|
|
Mesh
|
|
|
|
Mesh::LineTo(ObjectNameTag nameTag, const Vec3D &from, const Vec3D &to, double line_width, const sf::Color &color) {
|
2021-09-19 11:25:10 +03:00
|
|
|
|
2021-10-29 23:44:37 +03:00
|
|
|
Mesh line(std::move(nameTag));
|
2021-09-13 15:53:43 +03:00
|
|
|
|
2021-10-12 17:12:47 +03:00
|
|
|
Vec3D v1 = (to - from).normalized();
|
|
|
|
Vec3D v2 = from.cross(from + Vec3D{1, 0, 0}).normalized();
|
|
|
|
Vec3D v3 = v1.cross(v2).normalized();
|
2021-09-13 15:53:43 +03:00
|
|
|
|
|
|
|
// from plane
|
2021-10-28 16:58:02 +03:00
|
|
|
Vec4D p1 = (from - v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
|
|
|
|
Vec4D p2 = (from - v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
|
|
|
|
Vec4D p3 = (from + v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
|
|
|
|
Vec4D p4 = (from + v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
|
2021-09-13 15:53:43 +03:00
|
|
|
// to plane
|
2021-10-28 16:58:02 +03:00
|
|
|
Vec4D p5 = (to - v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
|
|
|
|
Vec4D p6 = (to - v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
|
|
|
|
Vec4D p7 = (to + v2 * line_width / 2.0 + v3 * line_width / 2.0).makePoint4D();
|
|
|
|
Vec4D p8 = (to + v2 * line_width / 2.0 - v3 * line_width / 2.0).makePoint4D();
|
2021-10-12 17:12:47 +03:00
|
|
|
|
2021-09-13 15:53:43 +03:00
|
|
|
|
2021-10-12 17:12:47 +03:00
|
|
|
line._tris = std::move(std::vector<Triangle>{
|
2021-10-31 11:39:08 +03:00
|
|
|
{p2, p4, p1},
|
|
|
|
{p2, p3, p4},
|
|
|
|
{p1, p6, p2},
|
|
|
|
{p1, p5, p6},
|
|
|
|
{p2, p6, p7},
|
|
|
|
{p2, p7, p3},
|
|
|
|
{p6, p5, p8},
|
|
|
|
{p6, p8, p7},
|
|
|
|
{p4, p3, p7},
|
|
|
|
{p4, p7, p8},
|
|
|
|
{p1, p8, p5},
|
|
|
|
{p1, p4, p8}
|
2021-10-12 17:12:47 +03:00
|
|
|
});
|
2021-09-13 15:53:43 +03:00
|
|
|
line.setColor(color);
|
|
|
|
|
|
|
|
return line;
|
|
|
|
}
|
2021-10-12 17:12:47 +03:00
|
|
|
|
|
|
|
void Mesh::setTriangles(const vector<Triangle> &t) {
|
|
|
|
_tris.clear();
|
2021-10-31 11:39:08 +03:00
|
|
|
for (auto &tri : t) {
|
2021-10-12 17:12:47 +03:00
|
|
|
_tris.push_back(tri);
|
|
|
|
}
|
|
|
|
}
|
2021-10-16 20:22:55 +03:00
|
|
|
|
2021-11-04 03:44:53 +03:00
|
|
|
void Mesh::setTriangles(vector<Triangle>&& t) {
|
|
|
|
_tris = std::move(t);
|
|
|
|
}
|
|
|
|
|
2021-10-16 20:22:55 +03:00
|
|
|
Mesh::~Mesh() {
|
|
|
|
_tris.clear();
|
2021-11-05 23:55:42 +03:00
|
|
|
delete[] _geometry;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLfloat *Mesh::glFloatArray() const {
|
|
|
|
if(_geometry != nullptr) {
|
|
|
|
return _geometry;
|
|
|
|
}
|
|
|
|
_geometry = new GLfloat[7 * 3 * _tris.size()];
|
|
|
|
|
|
|
|
for (size_t i = 0; i < _tris.size(); i++) {
|
|
|
|
|
|
|
|
unsigned stride = 21 * i;
|
|
|
|
|
|
|
|
Triangle triangle = _tris[i];
|
|
|
|
Vec3D norm = (model()*triangle.norm()).normalized();
|
|
|
|
float dot = static_cast<float>(norm.dot(Vec3D(0, 1, 2).normalized()));
|
|
|
|
|
|
|
|
for (int k = 0; k < 3; k++) {
|
|
|
|
sf::Color color = triangle.color();
|
|
|
|
GLfloat ambientColor[4] = {
|
|
|
|
static_cast<float>(color.r) * (0.3f * std::fabs(dot) + 0.7f) / 255.0f,
|
|
|
|
static_cast<float>(color.g) * (0.3f * std::fabs(dot) + 0.7f) / 255.0f,
|
|
|
|
static_cast<float>(color.b) * (0.3f * std::fabs(dot) + 0.7f) / 255.0f,
|
|
|
|
static_cast<float>(color.a) / 255.0f
|
|
|
|
};
|
|
|
|
|
|
|
|
_geometry[stride + 7 * k + 0] = static_cast<GLfloat>(triangle[k].x());
|
|
|
|
_geometry[stride + 7 * k + 1] = static_cast<GLfloat>(triangle[k].y());
|
|
|
|
_geometry[stride + 7 * k + 2] = static_cast<GLfloat>(triangle[k].z());
|
|
|
|
|
|
|
|
_geometry[stride + 7 * k + 3] = ambientColor[0];
|
|
|
|
_geometry[stride + 7 * k + 4] = ambientColor[1];
|
|
|
|
_geometry[stride + 7 * k + 5] = ambientColor[2];
|
|
|
|
_geometry[stride + 7 * k + 6] = ambientColor[3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return _geometry;
|
2021-10-16 20:22:55 +03:00
|
|
|
}
|