2018-04-26 02:23:22 +00:00
|
|
|
#include <assert.h>
|
2018-10-09 02:19:12 +00:00
|
|
|
#include <QTextStream>
|
|
|
|
#include <QFile>
|
2018-10-19 05:08:02 +00:00
|
|
|
#include <cmath>
|
2018-05-07 17:16:58 +00:00
|
|
|
#include "meshloader.h"
|
2018-10-09 02:19:12 +00:00
|
|
|
#include "ds3file.h"
|
2018-03-10 06:57:14 +00:00
|
|
|
|
2018-03-20 07:56:49 +00:00
|
|
|
#define MAX_VERTICES_PER_FACE 100
|
|
|
|
|
2018-10-09 02:19:12 +00:00
|
|
|
float MeshLoader::m_defaultMetalness = 0.0;
|
|
|
|
float MeshLoader::m_defaultRoughness = 1.0;
|
|
|
|
|
2018-06-11 14:24:25 +00:00
|
|
|
MeshLoader::MeshLoader(const MeshLoader &mesh) :
|
2018-05-10 09:16:22 +00:00
|
|
|
m_triangleVertices(nullptr),
|
|
|
|
m_triangleVertexCount(0),
|
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
|
|
|
{
|
2018-06-11 14:24:25 +00:00
|
|
|
if (nullptr != mesh.m_triangleVertices &&
|
|
|
|
mesh.m_triangleVertexCount > 0) {
|
|
|
|
this->m_triangleVertices = new Vertex[mesh.m_triangleVertexCount];
|
|
|
|
this->m_triangleVertexCount = mesh.m_triangleVertexCount;
|
|
|
|
for (int i = 0; i < mesh.m_triangleVertexCount; i++)
|
|
|
|
this->m_triangleVertices[i] = mesh.m_triangleVertices[i];
|
2018-05-10 09:16:22 +00:00
|
|
|
}
|
2018-06-11 14:24:25 +00:00
|
|
|
if (nullptr != mesh.m_edgeVertices &&
|
|
|
|
mesh.m_edgeVertexCount > 0) {
|
|
|
|
this->m_edgeVertices = new Vertex[mesh.m_edgeVertexCount];
|
|
|
|
this->m_edgeVertexCount = mesh.m_edgeVertexCount;
|
|
|
|
for (int i = 0; i < mesh.m_edgeVertexCount; i++)
|
|
|
|
this->m_edgeVertices[i] = mesh.m_edgeVertices[i];
|
|
|
|
}
|
|
|
|
if (nullptr != mesh.m_textureImage) {
|
|
|
|
this->m_textureImage = new QImage(*mesh.m_textureImage);
|
|
|
|
}
|
2018-10-09 02:19:12 +00:00
|
|
|
if (nullptr != mesh.m_normalMapImage) {
|
|
|
|
this->m_normalMapImage = new QImage(*mesh.m_normalMapImage);
|
|
|
|
}
|
2018-11-11 09:13:46 +00:00
|
|
|
if (nullptr != mesh.m_metalnessRoughnessAmbientOcclusionImage) {
|
|
|
|
this->m_metalnessRoughnessAmbientOcclusionImage = new QImage(*mesh.m_metalnessRoughnessAmbientOcclusionImage);
|
|
|
|
this->m_hasMetalnessInImage = mesh.m_hasMetalnessInImage;
|
|
|
|
this->m_hasRoughnessInImage = mesh.m_hasRoughnessInImage;
|
|
|
|
this->m_hasAmbientOcclusionInImage = mesh.m_hasAmbientOcclusionInImage;
|
|
|
|
}
|
2018-06-11 14:24:25 +00:00
|
|
|
this->m_vertices = mesh.m_vertices;
|
|
|
|
this->m_faces = mesh.m_faces;
|
|
|
|
this->m_triangulatedVertices = mesh.m_triangulatedVertices;
|
|
|
|
this->m_triangulatedFaces = mesh.m_triangulatedFaces;
|
|
|
|
}
|
|
|
|
|
|
|
|
MeshLoader::MeshLoader(Vertex *triangleVertices, int vertexNum) :
|
|
|
|
m_triangleVertices(triangleVertices),
|
|
|
|
m_triangleVertexCount(vertexNum),
|
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
|
|
|
{
|
2018-05-10 09:16:22 +00:00
|
|
|
}
|
|
|
|
|
2019-02-18 12:57:18 +00:00
|
|
|
MeshLoader::MeshLoader(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &triangles,
|
|
|
|
const std::vector<std::vector<QVector3D>> &triangleVertexNormals,
|
|
|
|
const QColor &color)
|
|
|
|
{
|
|
|
|
m_triangleVertexCount = triangles.size() * 3;
|
|
|
|
m_triangleVertices = new Vertex[m_triangleVertexCount];
|
|
|
|
int destIndex = 0;
|
|
|
|
for (size_t i = 0; i < triangles.size(); ++i) {
|
|
|
|
for (auto j = 0; j < 3; j++) {
|
|
|
|
int vertexIndex = triangles[i][j];
|
|
|
|
const QVector3D *srcVert = &vertices[vertexIndex];
|
|
|
|
const QVector3D *srcNormal = &(triangleVertexNormals)[i][j];
|
|
|
|
Vertex *dest = &m_triangleVertices[destIndex];
|
|
|
|
dest->colorR = color.redF();
|
|
|
|
dest->colorG = color.greenF();
|
|
|
|
dest->colorB = color.blueF();
|
|
|
|
dest->posX = srcVert->x();
|
|
|
|
dest->posY = srcVert->y();
|
|
|
|
dest->posZ = srcVert->z();
|
|
|
|
dest->texU = 0;
|
|
|
|
dest->texV = 0;
|
|
|
|
dest->normX = srcNormal->x();
|
|
|
|
dest->normY = srcNormal->y();
|
|
|
|
dest->normZ = srcNormal->z();
|
|
|
|
dest->metalness = m_defaultMetalness;
|
|
|
|
dest->roughness = m_defaultRoughness;
|
|
|
|
dest->tangentX = 0;
|
|
|
|
dest->tangentY = 0;
|
|
|
|
dest->tangentZ = 0;
|
|
|
|
destIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-25 00:19:38 +00:00
|
|
|
MeshLoader::MeshLoader(Outcome &outcome) :
|
2018-05-10 09:16:22 +00:00
|
|
|
m_triangleVertices(nullptr),
|
|
|
|
m_triangleVertexCount(0),
|
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
|
|
|
{
|
2019-02-18 12:57:18 +00:00
|
|
|
m_vertices = outcome.vertices;
|
|
|
|
m_faces = outcome.triangleAndQuads;
|
|
|
|
|
2018-10-26 23:04:45 +00:00
|
|
|
m_triangleVertexCount = outcome.triangles.size() * 3;
|
2018-05-10 09:16:22 +00:00
|
|
|
m_triangleVertices = new Vertex[m_triangleVertexCount];
|
|
|
|
int destIndex = 0;
|
2018-10-26 23:04:45 +00:00
|
|
|
const auto triangleVertexNormals = outcome.triangleVertexNormals();
|
|
|
|
const auto triangleVertexUvs = outcome.triangleVertexUvs();
|
|
|
|
const auto triangleTangents = outcome.triangleTangents();
|
|
|
|
const QVector3D defaultNormal = QVector3D(0, 0, 0);
|
|
|
|
const QVector2D defaultUv = QVector2D(0, 0);
|
|
|
|
const QVector3D defaultTangent = QVector3D(0, 0, 0);
|
|
|
|
for (size_t i = 0; i < outcome.triangles.size(); ++i) {
|
|
|
|
for (auto j = 0; j < 3; j++) {
|
|
|
|
int vertexIndex = outcome.triangles[i][j];
|
|
|
|
const QVector3D *srcVert = &outcome.vertices[vertexIndex];
|
|
|
|
const QVector3D *srcNormal = &defaultNormal;
|
|
|
|
if (triangleVertexNormals)
|
|
|
|
srcNormal = &(*triangleVertexNormals)[i][j];
|
|
|
|
const QVector2D *srcUv = &defaultUv;
|
|
|
|
if (triangleVertexUvs)
|
|
|
|
srcUv = &(*triangleVertexUvs)[i][j];
|
|
|
|
const QVector3D *srcTangent = &defaultTangent;
|
|
|
|
if (triangleTangents)
|
|
|
|
srcTangent = &(*triangleTangents)[i];
|
|
|
|
Vertex *dest = &m_triangleVertices[destIndex];
|
|
|
|
dest->colorR = 0;
|
|
|
|
dest->colorG = 0;
|
|
|
|
dest->colorB = 0;
|
|
|
|
dest->posX = srcVert->x();
|
|
|
|
dest->posY = srcVert->y();
|
|
|
|
dest->posZ = srcVert->z();
|
|
|
|
dest->texU = srcUv->x();
|
|
|
|
dest->texV = srcUv->y();
|
|
|
|
dest->normX = srcNormal->x();
|
|
|
|
dest->normY = srcNormal->y();
|
|
|
|
dest->normZ = srcNormal->z();
|
|
|
|
dest->metalness = m_defaultMetalness;
|
|
|
|
dest->roughness = m_defaultRoughness;
|
|
|
|
dest->tangentX = srcTangent->x();
|
|
|
|
dest->tangentY = srcTangent->y();
|
|
|
|
dest->tangentZ = srcTangent->z();
|
|
|
|
destIndex++;
|
2018-05-10 09:16:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-18 06:22:29 +00:00
|
|
|
MeshLoader::MeshLoader() :
|
|
|
|
m_triangleVertices(nullptr),
|
|
|
|
m_triangleVertexCount(0),
|
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
MeshLoader::~MeshLoader()
|
2018-03-10 06:57:14 +00:00
|
|
|
{
|
2018-03-19 13:56:10 +00:00
|
|
|
delete[] m_triangleVertices;
|
|
|
|
m_triangleVertexCount = 0;
|
2018-06-11 14:24:25 +00:00
|
|
|
delete[] m_edgeVertices;
|
|
|
|
m_edgeVertexCount = 0;
|
2018-05-10 09:16:22 +00:00
|
|
|
delete m_textureImage;
|
2018-10-09 02:19:12 +00:00
|
|
|
delete m_normalMapImage;
|
2018-11-11 09:13:46 +00:00
|
|
|
delete m_metalnessRoughnessAmbientOcclusionImage;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
const std::vector<QVector3D> &MeshLoader::vertices()
|
2018-03-20 07:56:49 +00:00
|
|
|
{
|
|
|
|
return m_vertices;
|
|
|
|
}
|
|
|
|
|
2019-02-18 12:57:18 +00:00
|
|
|
const std::vector<std::vector<size_t>> &MeshLoader::faces()
|
2018-03-20 07:56:49 +00:00
|
|
|
{
|
|
|
|
return m_faces;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
const std::vector<QVector3D> &MeshLoader::triangulatedVertices()
|
2018-04-26 02:23:22 +00:00
|
|
|
{
|
|
|
|
return m_triangulatedVertices;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
const std::vector<TriangulatedFace> &MeshLoader::triangulatedFaces()
|
2018-04-26 02:23:22 +00:00
|
|
|
{
|
|
|
|
return m_triangulatedFaces;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
Vertex *MeshLoader::triangleVertices()
|
2018-03-10 06:57:14 +00:00
|
|
|
{
|
2018-03-19 13:56:10 +00:00
|
|
|
return m_triangleVertices;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
int MeshLoader::triangleVertexCount()
|
2018-03-10 06:57:14 +00:00
|
|
|
{
|
2018-03-19 13:56:10 +00:00
|
|
|
return m_triangleVertexCount;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
2018-03-19 13:56:10 +00:00
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
Vertex *MeshLoader::edgeVertices()
|
2018-03-19 13:56:10 +00:00
|
|
|
{
|
|
|
|
return m_edgeVertices;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
int MeshLoader::edgeVertexCount()
|
2018-03-19 13:56:10 +00:00
|
|
|
{
|
|
|
|
return m_edgeVertexCount;
|
|
|
|
}
|
|
|
|
|
2018-05-10 09:16:22 +00:00
|
|
|
void MeshLoader::setTextureImage(QImage *textureImage)
|
|
|
|
{
|
|
|
|
m_textureImage = textureImage;
|
|
|
|
}
|
2018-03-19 13:56:10 +00:00
|
|
|
|
2018-05-10 09:16:22 +00:00
|
|
|
const QImage *MeshLoader::textureImage()
|
|
|
|
{
|
|
|
|
return m_textureImage;
|
|
|
|
}
|
2018-10-09 02:19:12 +00:00
|
|
|
|
|
|
|
void MeshLoader::setNormalMapImage(QImage *normalMapImage)
|
|
|
|
{
|
|
|
|
m_normalMapImage = normalMapImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QImage *MeshLoader::normalMapImage()
|
|
|
|
{
|
|
|
|
return m_normalMapImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QImage *MeshLoader::metalnessRoughnessAmbientOcclusionImage()
|
|
|
|
{
|
|
|
|
return m_metalnessRoughnessAmbientOcclusionImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MeshLoader::setMetalnessRoughnessAmbientOcclusionImage(QImage *image)
|
|
|
|
{
|
|
|
|
m_metalnessRoughnessAmbientOcclusionImage = image;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MeshLoader::hasMetalnessInImage()
|
|
|
|
{
|
|
|
|
return m_hasMetalnessInImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MeshLoader::setHasMetalnessInImage(bool hasInImage)
|
|
|
|
{
|
|
|
|
m_hasMetalnessInImage = hasInImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MeshLoader::hasRoughnessInImage()
|
|
|
|
{
|
|
|
|
return m_hasRoughnessInImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MeshLoader::setHasRoughnessInImage(bool hasInImage)
|
|
|
|
{
|
|
|
|
m_hasRoughnessInImage = hasInImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MeshLoader::hasAmbientOcclusionInImage()
|
|
|
|
{
|
|
|
|
return m_hasAmbientOcclusionInImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MeshLoader::setHasAmbientOcclusionInImage(bool hasInImage)
|
|
|
|
{
|
|
|
|
m_hasAmbientOcclusionInImage = hasInImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MeshLoader::exportAsObj(const QString &filename)
|
|
|
|
{
|
|
|
|
QFile file(filename);
|
|
|
|
if (file.open(QIODevice::WriteOnly)) {
|
|
|
|
QTextStream stream(&file);
|
|
|
|
stream << "# " << Ds3FileReader::m_applicationName << endl;
|
|
|
|
for (std::vector<QVector3D>::const_iterator it = vertices().begin() ; it != vertices().end(); ++it) {
|
|
|
|
stream << "v " << (*it).x() << " " << (*it).y() << " " << (*it).z() << endl;
|
|
|
|
}
|
2019-02-18 12:57:18 +00:00
|
|
|
for (std::vector<std::vector<size_t>>::const_iterator it = faces().begin() ; it != faces().end(); ++it) {
|
2018-10-09 02:19:12 +00:00
|
|
|
stream << "f";
|
2019-02-18 12:57:18 +00:00
|
|
|
for (std::vector<size_t>::const_iterator subIt = (*it).begin() ; subIt != (*it).end(); ++subIt) {
|
2018-10-09 02:19:12 +00:00
|
|
|
stream << " " << (1 + *subIt);
|
|
|
|
}
|
|
|
|
stream << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|