mesh is now partially serializable
This commit is contained in:
parent
82130abc9b
commit
0f0ff32f16
@ -82,7 +82,7 @@ void Chunk::generate(glm::vec3 pos)
|
|||||||
}
|
}
|
||||||
delete[](top);
|
delete[](top);
|
||||||
for(int id : m_indiceList)
|
for(int id : m_indiceList)
|
||||||
mesh->indices.push_back(m_vertexHashTable[id]);
|
mesh->m_indices.push_back(m_vertexHashTable[id]);
|
||||||
m_indiceList.clear();
|
m_indiceList.clear();
|
||||||
delete[] m_vertexHashTable;
|
delete[] m_vertexHashTable;
|
||||||
}
|
}
|
||||||
@ -197,11 +197,11 @@ glm::vec3 Chunk::createInterpolatedVertex(glm::vec3 p1, glm::vec3 p2, float valp
|
|||||||
p = p1 * (1-mu) + p2 * mu;
|
p = p1 * (1-mu) + p2 * mu;
|
||||||
|
|
||||||
// store vertice id in the hash table
|
// store vertice id in the hash table
|
||||||
m_vertexHashTable[hash] = mesh->positions3D.size();
|
m_vertexHashTable[hash] = mesh->m_positions3D.size();
|
||||||
|
|
||||||
// vertex creation from position p (estimated position of the surface)
|
// vertex creation from position p (estimated position of the surface)
|
||||||
mesh->positions3D.push_back(p);
|
mesh->m_positions3D.push_back(p);
|
||||||
mesh->normals.push_back(m_generator->grad(m_position + p));
|
mesh->m_normals.push_back(m_generator->grad(m_position + p));
|
||||||
}
|
}
|
||||||
|
|
||||||
// constants :
|
// constants :
|
||||||
|
@ -39,10 +39,10 @@ void ForwardModule::renderGL(Camera* myCamera, Scene* scene)
|
|||||||
for(GeometryNode *node : p.geometry)
|
for(GeometryNode *node : p.geometry)
|
||||||
{
|
{
|
||||||
shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id);
|
shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id);
|
||||||
if(node->mesh->instances_offsets.empty())
|
if(node->mesh->m_instances_offsets.empty())
|
||||||
++id;
|
++id;
|
||||||
else
|
else
|
||||||
id += node->mesh->instances_offsets.size();
|
id += node->mesh->m_instances_offsets.size();
|
||||||
// compute matrix attributes
|
// compute matrix attributes
|
||||||
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
|
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
|
||||||
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
|
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
|
||||||
|
411
src/mesh.cpp
411
src/mesh.cpp
@ -6,6 +6,8 @@
|
|||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
INIT_SERIALIZABLE(Mesh)
|
||||||
|
|
||||||
const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
|
const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
|
||||||
{
|
{
|
||||||
"INDEXED",
|
"INDEXED",
|
||||||
@ -34,8 +36,8 @@ const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
|
|||||||
"BUMP_MAP"
|
"BUMP_MAP"
|
||||||
};
|
};
|
||||||
|
|
||||||
Mesh::Mesh(const std::string &name) :
|
Mesh::Mesh() :
|
||||||
m_name(name),
|
m_name("mesh"),
|
||||||
material(NULL),
|
material(NULL),
|
||||||
isDoubleSided(false),
|
isDoubleSided(false),
|
||||||
isBillboard(false),
|
isBillboard(false),
|
||||||
@ -49,6 +51,12 @@ Mesh::Mesh(const std::string &name) :
|
|||||||
clearBuffers();
|
clearBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mesh::Mesh(const std::string &name) :
|
||||||
|
Mesh()
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
Mesh::~Mesh()
|
Mesh::~Mesh()
|
||||||
{
|
{
|
||||||
destroyGL();
|
destroyGL();
|
||||||
@ -73,18 +81,18 @@ unsigned int Mesh::updateFlags()
|
|||||||
{
|
{
|
||||||
m_flags = 0;
|
m_flags = 0;
|
||||||
|
|
||||||
if(!indices.empty())
|
if(!m_indices.empty())
|
||||||
m_flags |= 1 << MESH_INDEXED;
|
m_flags |= 1 << MESH_INDEXED;
|
||||||
if(!texCoords.empty())
|
if(!m_texCoords.empty())
|
||||||
m_flags |= 1 << MESH_TEXTURABLE;
|
m_flags |= 1 << MESH_TEXTURABLE;
|
||||||
if(!instances_offsets.empty())
|
if(!m_instances_offsets.empty())
|
||||||
m_flags |= 1 << MESH_INSTANCED;
|
m_flags |= 1 << MESH_INSTANCED;
|
||||||
|
|
||||||
if(!positions3D.empty())
|
if(!m_positions3D.empty())
|
||||||
{
|
{
|
||||||
m_flags |= 1 << MESH_3D;
|
m_flags |= 1 << MESH_3D;
|
||||||
|
|
||||||
if(!tangents.empty())
|
if(!m_tangents.empty())
|
||||||
m_flags |= 1 << MESH_TANGENT_SPACE;
|
m_flags |= 1 << MESH_TANGENT_SPACE;
|
||||||
if(isDoubleSided)
|
if(isDoubleSided)
|
||||||
m_flags |= 1 << MESH_DOUBLE_SIDED;
|
m_flags |= 1 << MESH_DOUBLE_SIDED;
|
||||||
@ -111,31 +119,31 @@ void Mesh::initGL()
|
|||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
// init positions VBO
|
// init positions VBO
|
||||||
if(!positions3D.empty())
|
if(!m_positions3D.empty())
|
||||||
{
|
{
|
||||||
auto posBuffer = new TBuffer<glm::vec3>(positions3D, Buffer::VBO);
|
auto posBuffer = new TBuffer<glm::vec3>(m_positions3D, Buffer::VBO);
|
||||||
posBuffer->setVertexAttrib(0, 3);
|
posBuffer->setVertexAttrib(0, 3);
|
||||||
addBuffer(posBuffer, POSITION3D_BUFFER);
|
addBuffer(posBuffer, POSITION3D_BUFFER);
|
||||||
|
|
||||||
// init normals vbo
|
// init normals vbo
|
||||||
if(!normals.empty())
|
if(!m_normals.empty())
|
||||||
{
|
{
|
||||||
auto normalsBuffer = new TBuffer<glm::vec3>(normals, Buffer::VBO);
|
auto normalsBuffer = new TBuffer<glm::vec3>(m_normals, Buffer::VBO);
|
||||||
normalsBuffer->setVertexAttrib(1, 3);
|
normalsBuffer->setVertexAttrib(1, 3);
|
||||||
addBuffer(normalsBuffer, NORMAL_BUFFER);
|
addBuffer(normalsBuffer, NORMAL_BUFFER);
|
||||||
}
|
}
|
||||||
// init tangents vbo
|
// init tangents vbo
|
||||||
if(!tangents.empty())
|
if(!m_tangents.empty())
|
||||||
{
|
{
|
||||||
auto tangentsBuffer = new TBuffer<Tangents>(tangents, Buffer::VBO);
|
auto tangentsBuffer = new TBuffer<Tangents>(m_tangents, Buffer::VBO);
|
||||||
tangentsBuffer->setVertexAttrib(3, 3, 0);
|
tangentsBuffer->setVertexAttrib(3, 3, 0);
|
||||||
tangentsBuffer->setVertexAttrib(4, 3, sizeof(glm::vec3));
|
tangentsBuffer->setVertexAttrib(4, 3, sizeof(glm::vec3));
|
||||||
addBuffer(tangentsBuffer, TANGENT_BUFFER);
|
addBuffer(tangentsBuffer, TANGENT_BUFFER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!positions2D.empty())
|
else if(!m_positions2D.empty())
|
||||||
{
|
{
|
||||||
auto posBuffer = new TBuffer<glm::vec2>(positions2D, Buffer::VBO);
|
auto posBuffer = new TBuffer<glm::vec2>(m_positions2D, Buffer::VBO);
|
||||||
posBuffer->setVertexAttrib(0, 2);
|
posBuffer->setVertexAttrib(0, 2);
|
||||||
addBuffer(posBuffer, POSITION2D_BUFFER);
|
addBuffer(posBuffer, POSITION2D_BUFFER);
|
||||||
}
|
}
|
||||||
@ -145,25 +153,25 @@ void Mesh::initGL()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// init texCoords vbo
|
// init texCoords vbo
|
||||||
if(!texCoords.empty())
|
if(!m_texCoords.empty())
|
||||||
{
|
{
|
||||||
auto texCoordBuffer = new TBuffer<glm::vec2>(texCoords, Buffer::VBO);
|
auto texCoordBuffer = new TBuffer<glm::vec2>(m_texCoords, Buffer::VBO);
|
||||||
texCoordBuffer->setVertexAttrib(2, 2);
|
texCoordBuffer->setVertexAttrib(2, 2);
|
||||||
addBuffer(texCoordBuffer, TEXCOORD_BUFFER);
|
addBuffer(texCoordBuffer, TEXCOORD_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// init instances vbo
|
// init instances vbo
|
||||||
if(!instances_offsets.empty())
|
if(!m_instances_offsets.empty())
|
||||||
{
|
{
|
||||||
auto instancesBuffer = new TBuffer<glm::vec3>(instances_offsets, Buffer::VBO);
|
auto instancesBuffer = new TBuffer<glm::vec3>(m_instances_offsets, Buffer::VBO);
|
||||||
instancesBuffer->setVertexAttrib(5, 3, 0, 1);
|
instancesBuffer->setVertexAttrib(5, 3, 0, 1);
|
||||||
addBuffer(instancesBuffer, INSTANCE_BUFFER);
|
addBuffer(instancesBuffer, INSTANCE_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// init EBO
|
// init EBO
|
||||||
if(!indices.empty())
|
if(!m_indices.empty())
|
||||||
{
|
{
|
||||||
auto indicesBuffer = new TBuffer<GLuint>(indices, Buffer::EBO);
|
auto indicesBuffer = new TBuffer<GLuint>(m_indices, Buffer::EBO);
|
||||||
addBuffer(indicesBuffer, INDICES_BUFFER);
|
addBuffer(indicesBuffer, INDICES_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,12 +191,12 @@ void Mesh::draw(Shader* shader)
|
|||||||
material->bindAttributes(shader);
|
material->bindAttributes(shader);
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
if(indices.empty())
|
if(m_indices.empty())
|
||||||
{
|
{
|
||||||
int size = positions3D.empty() ? positions2D.size() : positions3D.size();
|
int size = m_positions3D.empty() ? m_positions2D.size() : m_positions3D.size();
|
||||||
if(!instances_offsets.empty())
|
if(!m_instances_offsets.empty())
|
||||||
{
|
{
|
||||||
glDrawArraysInstanced(primitive_type, 0, size, instances_offsets.size());
|
glDrawArraysInstanced(primitive_type, 0, size, m_instances_offsets.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -199,13 +207,13 @@ void Mesh::draw(Shader* shader)
|
|||||||
{
|
{
|
||||||
Buffer *b = buffers[buffersId[INDICES_BUFFER]];
|
Buffer *b = buffers[buffersId[INDICES_BUFFER]];
|
||||||
b->bind();
|
b->bind();
|
||||||
if(!instances_offsets.empty())
|
if(!m_instances_offsets.empty())
|
||||||
{
|
{
|
||||||
glDrawElementsInstanced(primitive_type, indices.size(), GL_UNSIGNED_INT, NULL, instances_offsets.size());
|
glDrawElementsInstanced(primitive_type, m_indices.size(), GL_UNSIGNED_INT, NULL, m_instances_offsets.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glDrawElements(primitive_type, indices.size(), GL_UNSIGNED_INT, NULL);
|
glDrawElements(primitive_type, m_indices.size(), GL_UNSIGNED_INT, NULL);
|
||||||
}
|
}
|
||||||
b->unbind();
|
b->unbind();
|
||||||
}
|
}
|
||||||
@ -227,13 +235,13 @@ void Mesh::destroyGL()
|
|||||||
|
|
||||||
void Mesh::clearData()
|
void Mesh::clearData()
|
||||||
{
|
{
|
||||||
positions3D.clear();
|
m_positions3D.clear();
|
||||||
normals.clear();
|
m_normals.clear();
|
||||||
tangents.clear();
|
m_tangents.clear();
|
||||||
positions2D.clear();
|
m_positions2D.clear();
|
||||||
texCoords.clear();
|
m_texCoords.clear();
|
||||||
instances_offsets.clear();
|
m_instances_offsets.clear();
|
||||||
indices.clear();
|
m_indices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Mesh::getFlags()
|
unsigned int Mesh::getFlags()
|
||||||
@ -309,27 +317,27 @@ struct VertexComparator
|
|||||||
|
|
||||||
bool operator() (const int& vertId1, const int& vertId2) const
|
bool operator() (const int& vertId1, const int& vertId2) const
|
||||||
{
|
{
|
||||||
if(mesh->positions3D[vertId1].x != mesh->positions3D[vertId2].x)
|
if(mesh->m_positions3D[vertId1].x != mesh->m_positions3D[vertId2].x)
|
||||||
return (mesh->positions3D[vertId1].x < mesh->positions3D[vertId2].x);
|
return (mesh->m_positions3D[vertId1].x < mesh->m_positions3D[vertId2].x);
|
||||||
if(mesh->positions3D[vertId1].y != mesh->positions3D[vertId2].y)
|
if(mesh->m_positions3D[vertId1].y != mesh->m_positions3D[vertId2].y)
|
||||||
return (mesh->positions3D[vertId1].y < mesh->positions3D[vertId2].y);
|
return (mesh->m_positions3D[vertId1].y < mesh->m_positions3D[vertId2].y);
|
||||||
if(mesh->positions3D[vertId1].z != mesh->positions3D[vertId2].z)
|
if(mesh->m_positions3D[vertId1].z != mesh->m_positions3D[vertId2].z)
|
||||||
return (mesh->positions3D[vertId1].z < mesh->positions3D[vertId2].z);
|
return (mesh->m_positions3D[vertId1].z < mesh->m_positions3D[vertId2].z);
|
||||||
if(!mesh->texCoords.empty())
|
if(!mesh->m_texCoords.empty())
|
||||||
{
|
{
|
||||||
if(mesh->texCoords[vertId1].x - floor(mesh->texCoords[vertId1].x) != mesh->texCoords[vertId2].x - floor(mesh->texCoords[vertId2].x))
|
if(mesh->m_texCoords[vertId1].x - floor(mesh->m_texCoords[vertId1].x) != mesh->m_texCoords[vertId2].x - floor(mesh->m_texCoords[vertId2].x))
|
||||||
return (mesh->texCoords[vertId1].x < mesh->texCoords[vertId2].x);
|
return (mesh->m_texCoords[vertId1].x < mesh->m_texCoords[vertId2].x);
|
||||||
if(mesh->texCoords[vertId1].y - floor(mesh->texCoords[vertId1].y) != mesh->texCoords[vertId2].y - floor(mesh->texCoords[vertId2].y))
|
if(mesh->m_texCoords[vertId1].y - floor(mesh->m_texCoords[vertId1].y) != mesh->m_texCoords[vertId2].y - floor(mesh->m_texCoords[vertId2].y))
|
||||||
return (mesh->texCoords[vertId1].y < mesh->texCoords[vertId2].y);
|
return (mesh->m_texCoords[vertId1].y < mesh->m_texCoords[vertId2].y);
|
||||||
}
|
}
|
||||||
if(!mesh->normals.empty())
|
if(!mesh->m_normals.empty())
|
||||||
{
|
{
|
||||||
if(mesh->normals[vertId1].x != mesh->normals[vertId2].x)
|
if(mesh->m_normals[vertId1].x != mesh->m_normals[vertId2].x)
|
||||||
return (mesh->normals[vertId1].x < mesh->normals[vertId2].x);
|
return (mesh->m_normals[vertId1].x < mesh->m_normals[vertId2].x);
|
||||||
if(mesh->normals[vertId1].y != mesh->normals[vertId2].y)
|
if(mesh->m_normals[vertId1].y != mesh->m_normals[vertId2].y)
|
||||||
return (mesh->normals[vertId1].y < mesh->normals[vertId2].y);
|
return (mesh->m_normals[vertId1].y < mesh->m_normals[vertId2].y);
|
||||||
if(mesh->normals[vertId1].z != mesh->normals[vertId2].z)
|
if(mesh->m_normals[vertId1].z != mesh->m_normals[vertId2].z)
|
||||||
return (mesh->normals[vertId1].z < mesh->normals[vertId2].z);
|
return (mesh->m_normals[vertId1].z < mesh->m_normals[vertId2].z);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -339,29 +347,29 @@ Mesh* VertexComparator::mesh = NULL;
|
|||||||
|
|
||||||
void Mesh::mergeVertices()
|
void Mesh::mergeVertices()
|
||||||
{
|
{
|
||||||
if(positions3D.empty())
|
if(m_positions3D.empty())
|
||||||
return;
|
return;
|
||||||
bool *deleted = new bool[positions3D.size()];
|
bool *deleted = new bool[m_positions3D.size()];
|
||||||
int *offsets = new int[positions3D.size()];
|
int *offsets = new int[m_positions3D.size()];
|
||||||
std::set<int, VertexComparator> vertexSet;
|
std::set<int, VertexComparator> vertexSet;
|
||||||
VertexComparator::setMesh(this);
|
VertexComparator::setMesh(this);
|
||||||
|
|
||||||
for(std::size_t i=0; i<indices.size(); ++i)
|
for(std::size_t i=0; i<m_indices.size(); ++i)
|
||||||
{
|
{
|
||||||
std::pair<std::set<int,VertexComparator>::iterator, bool> ret = vertexSet.insert(indices[i]);
|
std::pair<std::set<int,VertexComparator>::iterator, bool> ret = vertexSet.insert(m_indices[i]);
|
||||||
std::set<int,VertexComparator>::iterator it = ret.first;
|
std::set<int,VertexComparator>::iterator it = ret.first;
|
||||||
bool success = ret.second;
|
bool success = ret.second;
|
||||||
deleted[indices[i]] = !success && *it != int(indices[i]);
|
deleted[m_indices[i]] = !success && *it != int(m_indices[i]);
|
||||||
if(deleted[indices[i]])
|
if(deleted[m_indices[i]])
|
||||||
{
|
{
|
||||||
if(!tangents.empty())
|
if(!m_tangents.empty())
|
||||||
tangents[*it].tangent += tangents[indices[i]].tangent;
|
m_tangents[*it].tangent += m_tangents[m_indices[i]].tangent;
|
||||||
indices[i] = *it;
|
m_indices[i] = *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for(std::size_t i=0; i<positions3D.size(); ++i)
|
for(std::size_t i=0; i<m_positions3D.size(); ++i)
|
||||||
{
|
{
|
||||||
if(deleted[i])
|
if(deleted[i])
|
||||||
++offset;
|
++offset;
|
||||||
@ -370,86 +378,86 @@ void Mesh::mergeVertices()
|
|||||||
offsets[i] = offset;
|
offsets[i] = offset;
|
||||||
if(offset != 0)
|
if(offset != 0)
|
||||||
{
|
{
|
||||||
positions3D[pos] = positions3D[i];
|
m_positions3D[pos] = m_positions3D[i];
|
||||||
if(!texCoords.empty())
|
if(!m_texCoords.empty())
|
||||||
texCoords[pos] = texCoords[i];
|
m_texCoords[pos] = m_texCoords[i];
|
||||||
if(!normals.empty())
|
if(!m_normals.empty())
|
||||||
normals[pos] = normals[i];
|
m_normals[pos] = m_normals[i];
|
||||||
if(!tangents.empty())
|
if(!m_tangents.empty())
|
||||||
tangents[pos] = tangents[i];
|
m_tangents[pos] = m_tangents[i];
|
||||||
}
|
}
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(std::size_t i=0; i<indices.size(); ++i)
|
for(std::size_t i=0; i<m_indices.size(); ++i)
|
||||||
indices[i] -= offsets[indices[i]];
|
m_indices[i] -= offsets[m_indices[i]];
|
||||||
|
|
||||||
positions3D.resize(positions3D.size()-offset);
|
m_positions3D.resize(m_positions3D.size()-offset);
|
||||||
if(!texCoords.empty())
|
if(!m_texCoords.empty())
|
||||||
texCoords.resize(texCoords.size()-offset);
|
m_texCoords.resize(m_texCoords.size()-offset);
|
||||||
if(!normals.empty())
|
if(!m_normals.empty())
|
||||||
normals.resize(normals.size()-offset);
|
m_normals.resize(m_normals.size()-offset);
|
||||||
if(!tangents.empty())
|
if(!m_tangents.empty())
|
||||||
tangents.resize(tangents.size()-offset);
|
m_tangents.resize(m_tangents.size()-offset);
|
||||||
for(int i=0; i<int(tangents.size()); ++i)
|
for(int i=0; i<int(m_tangents.size()); ++i)
|
||||||
{
|
{
|
||||||
glm::vec3 &T = tangents[i].tangent;
|
glm::vec3 &T = m_tangents[i].tangent;
|
||||||
const glm::vec3 &N = normals[i];
|
const glm::vec3 &N = m_normals[i];
|
||||||
|
|
||||||
T = glm::normalize(T);
|
T = glm::normalize(T);
|
||||||
// re-orthogonalize T with respect to N
|
// re-orthogonalize T with respect to N
|
||||||
T = glm::normalize(T - glm::dot(T, N) * N);
|
T = glm::normalize(T - glm::dot(T, N) * N);
|
||||||
// then retrieve perpendicular vector B with the cross product of T and N
|
// then retrieve perpendicular vector B with the cross product of T and N
|
||||||
tangents[i].binormal = glm::normalize(glm::cross(T, N));
|
m_tangents[i].binormal = glm::normalize(glm::cross(T, N));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::computeNeighbors()
|
void Mesh::computeNeighbors()
|
||||||
{
|
{
|
||||||
if(positions3D.empty())
|
if(m_positions3D.empty())
|
||||||
return;
|
return;
|
||||||
// TODO : compute adjacency and change primitivetype
|
// TODO : compute adjacency and change primitivetype
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::computeNormals()
|
void Mesh::computeNormals()
|
||||||
{
|
{
|
||||||
if(positions3D.empty())
|
if(m_positions3D.empty())
|
||||||
return;
|
return;
|
||||||
normals.resize(positions3D.size());
|
m_normals.resize(m_positions3D.size());
|
||||||
std::memset(normals.data(), 0, normals.size());
|
std::memset(m_normals.data(), 0, m_normals.size());
|
||||||
for (std::size_t i=0; i < indices.size(); i += 3)
|
for (std::size_t i=0; i < m_indices.size(); i += 3)
|
||||||
{
|
{
|
||||||
int v0 = indices[i];
|
int v0 = m_indices[i];
|
||||||
int v1 = indices[i+1];
|
int v1 = m_indices[i+1];
|
||||||
int v2 = indices[i+2];
|
int v2 = m_indices[i+2];
|
||||||
glm::vec3 n = glm::cross(positions3D[v1] - positions3D[v0], positions3D[v2] - positions3D[v0]);
|
glm::vec3 n = glm::cross(m_positions3D[v1] - m_positions3D[v0], m_positions3D[v2] - m_positions3D[v0]);
|
||||||
normals[v0] += n;
|
m_normals[v0] += n;
|
||||||
normals[v1] += n;
|
m_normals[v1] += n;
|
||||||
normals[v2] += n;
|
m_normals[v2] += n;
|
||||||
}
|
}
|
||||||
for(glm::vec3 &n : normals)
|
for(glm::vec3 &n : m_normals)
|
||||||
n = glm::normalize(n);
|
n = glm::normalize(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::computeTangents()
|
void Mesh::computeTangents()
|
||||||
{
|
{
|
||||||
if(texCoords.empty())
|
if(m_texCoords.empty())
|
||||||
return;
|
return;
|
||||||
tangents = std::vector<Tangents>(positions3D.size());
|
m_tangents = std::vector<Tangents>(m_positions3D.size());
|
||||||
|
|
||||||
for (std::size_t j=0; j < indices.size(); j += 3)
|
for (std::size_t j=0; j < m_indices.size(); j += 3)
|
||||||
{
|
{
|
||||||
int vertexId0 = indices[j];
|
int vertexId0 = m_indices[j];
|
||||||
int vertexId1 = indices[j+1];
|
int vertexId1 = m_indices[j+1];
|
||||||
int vertexId2 = indices[j+2];
|
int vertexId2 = m_indices[j+2];
|
||||||
|
|
||||||
const glm::vec3 &v1 = positions3D[vertexId0];
|
const glm::vec3 &v1 = m_positions3D[vertexId0];
|
||||||
glm::vec3 edge1 = positions3D[vertexId1] - v1;
|
glm::vec3 edge1 = m_positions3D[vertexId1] - v1;
|
||||||
glm::vec3 edge2 = positions3D[vertexId2] - v1;
|
glm::vec3 edge2 = m_positions3D[vertexId2] - v1;
|
||||||
|
|
||||||
const glm::vec2& w1 = texCoords[vertexId0];
|
const glm::vec2& w1 = m_texCoords[vertexId0];
|
||||||
glm::vec2 deltaUV1 = texCoords[vertexId1] - w1;
|
glm::vec2 deltaUV1 = m_texCoords[vertexId1] - w1;
|
||||||
glm::vec2 deltaUV2 = texCoords[vertexId2] - w1;
|
glm::vec2 deltaUV2 = m_texCoords[vertexId2] - w1;
|
||||||
|
|
||||||
float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
|
float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
|
||||||
|
|
||||||
@ -458,19 +466,19 @@ void Mesh::computeTangents()
|
|||||||
|
|
||||||
glm::vec3 binormalDir = deltaUV1.x * edge2 - deltaUV2.x * edge1;
|
glm::vec3 binormalDir = deltaUV1.x * edge2 - deltaUV2.x * edge1;
|
||||||
binormalDir = glm::normalize(binormalDir*f);
|
binormalDir = glm::normalize(binormalDir*f);
|
||||||
if(glm::dot(glm::cross(normals[vertexId0], binormalDir), tangentDir) < 0.f)
|
if(glm::dot(glm::cross(m_normals[vertexId0], binormalDir), tangentDir) < 0.f)
|
||||||
binormalDir = -binormalDir;
|
binormalDir = -binormalDir;
|
||||||
|
|
||||||
tangents[vertexId0] = {tangentDir, binormalDir};
|
m_tangents[vertexId0] = {tangentDir, binormalDir};
|
||||||
tangents[vertexId1] = {tangentDir, binormalDir};
|
m_tangents[vertexId1] = {tangentDir, binormalDir};
|
||||||
tangents[vertexId2] = {tangentDir, binormalDir};
|
m_tangents[vertexId2] = {tangentDir, binormalDir};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::computeBoundingBox(glm::vec3 &min, glm::vec3 &max)
|
void Mesh::computeBoundingBox(glm::vec3 &min, glm::vec3 &max)
|
||||||
{
|
{
|
||||||
min = max = positions3D[0];
|
min = max = m_positions3D[0];
|
||||||
for(const glm::vec3 &pos : positions3D)
|
for(const glm::vec3 &pos : m_positions3D)
|
||||||
{
|
{
|
||||||
if(pos.x < min.x)
|
if(pos.x < min.x)
|
||||||
min.x = pos.x;
|
min.x = pos.x;
|
||||||
@ -486,176 +494,3 @@ void Mesh::computeBoundingBox(glm::vec3 &min, glm::vec3 &max)
|
|||||||
max.z = pos.z;
|
max.z = pos.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialisation methods
|
|
||||||
|
|
||||||
struct MeshHeader
|
|
||||||
{
|
|
||||||
unsigned int flags;
|
|
||||||
int nbPositions;
|
|
||||||
int depth;
|
|
||||||
int nbInstances_offsets;
|
|
||||||
int nbIndices;
|
|
||||||
int nameLength;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool writeBuffer(const std::vector<T> &vec, std::FILE *file)
|
|
||||||
{
|
|
||||||
size_t nbWritten = std::fwrite(vec.data(), sizeof(T), vec.size(), file);
|
|
||||||
return (nbWritten == vec.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool readBuffer(std::vector<T> &vec, std::FILE *file)
|
|
||||||
{
|
|
||||||
size_t nbRead = std::fread(vec.data(), sizeof(T), vec.size(), file);
|
|
||||||
return (nbRead == vec.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Mesh::serialize(Mesh* mesh, FILE *file)
|
|
||||||
{
|
|
||||||
// creating header
|
|
||||||
MeshHeader header;
|
|
||||||
header.flags = mesh->getFlags();
|
|
||||||
if(header.flags & (1 << Mesh::MESH_3D))
|
|
||||||
header.nbPositions = mesh->positions3D.size();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
header.nbPositions = mesh->positions2D.size();
|
|
||||||
header.depth = mesh->getDepth();
|
|
||||||
}
|
|
||||||
header.nbIndices = mesh->indices.size();
|
|
||||||
header.nbInstances_offsets = mesh->instances_offsets.size();
|
|
||||||
header.nameLength = mesh->getName().size();
|
|
||||||
|
|
||||||
if(header.nbPositions == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// writing header
|
|
||||||
size_t nbWritten;
|
|
||||||
|
|
||||||
nbWritten = std::fwrite(&header, sizeof(MeshHeader), 1, file);
|
|
||||||
if(nbWritten != 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(header.nameLength != 0)
|
|
||||||
{
|
|
||||||
nbWritten = std::fwrite(mesh->getName().data(), header.nameLength, 1, file);
|
|
||||||
if(nbWritten != 1)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// writing buffers
|
|
||||||
if(header.flags & (1 << Mesh::MESH_3D))
|
|
||||||
{
|
|
||||||
if(!writeBuffer(mesh->positions3D, file))
|
|
||||||
return false;
|
|
||||||
if(mesh->normals.size() == 0)
|
|
||||||
mesh->computeNormals();
|
|
||||||
if(!writeBuffer(mesh->normals, file))
|
|
||||||
return false;
|
|
||||||
if(header.flags & (1 << Mesh::MESH_TANGENT_SPACE))
|
|
||||||
{
|
|
||||||
if(!writeBuffer(mesh->tangents, file))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!writeBuffer(mesh->positions2D, file))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(header.nbInstances_offsets)
|
|
||||||
{
|
|
||||||
if(!writeBuffer(mesh->instances_offsets, file))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(header.nbIndices)
|
|
||||||
{
|
|
||||||
if(!writeBuffer(mesh->indices, file))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(header.flags & (1 << Mesh::MESH_TEXTURABLE))
|
|
||||||
{
|
|
||||||
if(!writeBuffer(mesh->texCoords, file))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mesh* Mesh::deserialize(FILE *file)
|
|
||||||
{
|
|
||||||
MeshHeader header;
|
|
||||||
size_t nbRead = std::fread(&header, sizeof(MeshHeader), 1, file);
|
|
||||||
|
|
||||||
// deserializing mesh
|
|
||||||
Mesh *mesh = NULL;
|
|
||||||
if(nbRead == 1 && header.nbPositions != 0)
|
|
||||||
mesh = new Mesh();
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
std::string name = "mesh";
|
|
||||||
if(header.nameLength != 0)
|
|
||||||
{
|
|
||||||
name.resize(header.nameLength);
|
|
||||||
if(!fread(&(name[0]), header.nameLength, 1, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
}
|
|
||||||
mesh->setName(name);
|
|
||||||
|
|
||||||
if(header.flags & (1 << Mesh::MESH_3D))
|
|
||||||
{
|
|
||||||
mesh->positions3D.reserve(header.nbPositions);
|
|
||||||
if(!readBuffer(mesh->positions3D, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
mesh->normals.reserve(header.nbPositions);
|
|
||||||
if(!readBuffer(mesh->normals, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
if(header.flags & (1 << Mesh::MESH_TANGENT_SPACE))
|
|
||||||
{
|
|
||||||
mesh->tangents.reserve(header.nbPositions);
|
|
||||||
if(!readBuffer(mesh->tangents, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mesh->positions2D.reserve(header.nbPositions);
|
|
||||||
if(!readBuffer(mesh->positions2D, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
mesh->setDepth(header.depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(header.nbInstances_offsets)
|
|
||||||
{
|
|
||||||
mesh->instances_offsets.reserve(header.nbInstances_offsets);
|
|
||||||
if(!readBuffer(mesh->instances_offsets, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
}
|
|
||||||
|
|
||||||
if(header.nbIndices)
|
|
||||||
{
|
|
||||||
mesh->indices.reserve(header.nbIndices);
|
|
||||||
if(!readBuffer(mesh->indices, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
}
|
|
||||||
|
|
||||||
if(header.flags & (1 << Mesh::MESH_TEXTURABLE))
|
|
||||||
{
|
|
||||||
mesh->texCoords.reserve(header.nbPositions);
|
|
||||||
if(!readBuffer(mesh->texCoords, file))
|
|
||||||
{ delete(mesh); return NULL; }
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh->setIsBillboard(header.flags & (1 << Mesh::MESH_BILLBOARD));
|
|
||||||
mesh->setIsDoubleSided(header.flags & (1 << Mesh::MESH_DOUBLE_SIDED));
|
|
||||||
mesh->setIsShadowCaster(header.flags & (1 << Mesh::MESH_SHADOWED));
|
|
||||||
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
|
95
src/mesh.h
95
src/mesh.h
@ -7,11 +7,13 @@
|
|||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
|
#include <SparrowSerializer/serializable.h>
|
||||||
|
|
||||||
class Buffer;
|
class Buffer;
|
||||||
class Material;
|
class Material;
|
||||||
class Shader;
|
class Shader;
|
||||||
|
|
||||||
struct Mesh
|
struct Mesh : public Serializable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -63,33 +65,42 @@ public:
|
|||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
// 3D public data
|
// 3D public data
|
||||||
std::vector<glm::vec3> positions3D;
|
P_VECTOR_VEC3(m_positions3D)
|
||||||
std::vector<glm::vec3> normals;
|
P_VECTOR_VEC3(m_normals)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
glm::vec3 tangent;
|
glm::vec3 tangent;
|
||||||
glm::vec3 binormal;
|
glm::vec3 binormal;
|
||||||
} Tangents;
|
} Tangents;
|
||||||
|
|
||||||
std::vector<Tangents> tangents;
|
std::vector<Tangents> m_tangents;
|
||||||
|
|
||||||
// 2D public data
|
// 2D public data
|
||||||
std::vector<glm::vec2> positions2D;
|
P_VECTOR_VEC2(m_positions2D)
|
||||||
|
|
||||||
// public data common to 2D and 3D
|
// public data common to 2D and 3D
|
||||||
std::vector<glm::vec2> texCoords;
|
P_VECTOR_VEC2(m_texCoords)
|
||||||
std::vector<glm::vec3> instances_offsets;
|
P_VECTOR_VEC3(m_instances_offsets)
|
||||||
std::vector<GLuint> indices;
|
P_VECTOR_UINT(m_indices)
|
||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
/* MAIN METHODS */
|
/* MAIN METHODS */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
|
SERIALIZABLE(Mesh,
|
||||||
|
CAST(m_positions3D),
|
||||||
|
CAST(m_normals),
|
||||||
|
CAST(m_positions2D),
|
||||||
|
CAST(m_texCoords),
|
||||||
|
CAST(m_instances_offsets),
|
||||||
|
CAST(m_indices))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mesh builds an empty mesh, to be renderable, a mesh must have vertices and a material.
|
* @brief Mesh builds an empty mesh, to be renderable, a mesh must have vertices and a material.
|
||||||
*/
|
*/
|
||||||
Mesh(const std::string &name = "mesh");
|
Mesh();
|
||||||
|
Mesh(const std::string &name);
|
||||||
~Mesh();
|
~Mesh();
|
||||||
|
|
||||||
void setName(const std::string &name) { m_name = name; }
|
void setName(const std::string &name) { m_name = name; }
|
||||||
@ -122,9 +133,9 @@ public:
|
|||||||
|
|
||||||
// add vertex
|
// add vertex
|
||||||
void addVertex(float x, float y, float z) {addVertex(glm::vec3(x, y, z));}
|
void addVertex(float x, float y, float z) {addVertex(glm::vec3(x, y, z));}
|
||||||
void addVertex(const glm::vec3 &position) {positions3D.push_back(position);}
|
void addVertex(const glm::vec3 &position) {m_positions3D.push_back(position);}
|
||||||
void addVertex(float x, float y) {addVertex(glm::vec2(x, y));}
|
void addVertex(float x, float y) {addVertex(glm::vec2(x, y));}
|
||||||
void addVertex(const glm::vec2 &position) {positions2D.push_back(position);}
|
void addVertex(const glm::vec2 &position) {m_positions2D.push_back(position);}
|
||||||
void addVertex(const glm::vec3 &position, const glm::vec2 &texCoord) {addVertex(position); addTexCoord(texCoord);}
|
void addVertex(const glm::vec3 &position, const glm::vec2 &texCoord) {addVertex(position); addTexCoord(texCoord);}
|
||||||
void addVertex(const glm::vec2 &position, const glm::vec2 &texCoord) {addVertex(position); addTexCoord(texCoord);}
|
void addVertex(const glm::vec2 &position, const glm::vec2 &texCoord) {addVertex(position); addTexCoord(texCoord);}
|
||||||
void addVertex(const glm::vec3 &position, const glm::vec3 &normal) {addVertex(position); addNormal(normal);}
|
void addVertex(const glm::vec3 &position, const glm::vec3 &normal) {addVertex(position); addNormal(normal);}
|
||||||
@ -134,8 +145,8 @@ public:
|
|||||||
void addRectangle2D(float x, float y, float width, float height, bool indexed = false) {addRectangle2D(glm::vec2(x, y), glm::vec2(width, height), indexed);}
|
void addRectangle2D(float x, float y, float width, float height, bool indexed = false) {addRectangle2D(glm::vec2(x, y), glm::vec2(width, height), indexed);}
|
||||||
|
|
||||||
// add indices
|
// add indices
|
||||||
void addTriangle(int i1, int i2, int i3) {indices.push_back(i1), indices.push_back(i2), indices.push_back(i3);}
|
void addTriangle(int i1, int i2, int i3) {m_indices.push_back(i1), m_indices.push_back(i2), m_indices.push_back(i3);}
|
||||||
void addLine(int i1, int i2) {indices.push_back(i1), indices.push_back(i2);}
|
void addLine(int i1, int i2) {m_indices.push_back(i1), m_indices.push_back(i2);}
|
||||||
|
|
||||||
// Material accessers
|
// Material accessers
|
||||||
void setMaterial(Material* mat) {material = mat;}
|
void setMaterial(Material* mat) {material = mat;}
|
||||||
@ -143,9 +154,9 @@ public:
|
|||||||
|
|
||||||
// other accessers
|
// other accessers
|
||||||
void addNormal(float x, float y, float z) {addNormal(glm::vec3(x, y, z));}
|
void addNormal(float x, float y, float z) {addNormal(glm::vec3(x, y, z));}
|
||||||
void addNormal(const glm::vec3 &normal) {normals.push_back(normal);}
|
void addNormal(const glm::vec3 &normal) {m_normals.push_back(normal);}
|
||||||
void addTexCoord(float u, float v) {addTexCoord(glm::vec2(u, v));}
|
void addTexCoord(float u, float v) {addTexCoord(glm::vec2(u, v));}
|
||||||
void addTexCoord(const glm::vec2 &texCoord) {texCoords.push_back(texCoord);}
|
void addTexCoord(const glm::vec2 &texCoord) {m_texCoords.push_back(texCoord);}
|
||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
/* 2D MESH PROPERTIES */
|
/* 2D MESH PROPERTIES */
|
||||||
@ -196,43 +207,25 @@ public:
|
|||||||
void mergeVertices();
|
void mergeVertices();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief computeNormals computes adjacency for a triangle mesh, the mesh type changes to GL_TRIANGLES_ADJACENCY
|
* @brief computeNeighbors computes adjacency for a triangle mesh, the mesh type changes to GL_TRIANGLES_ADJACENCY
|
||||||
*/
|
*/
|
||||||
void computeNeighbors();
|
void computeNeighbors();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compute normals from an indexed mesh (positions + indices)
|
* @brief computeNormals computes normals from an indexed mesh (positions + indices)
|
||||||
*/
|
*/
|
||||||
void computeNormals();
|
void computeNormals();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compute tangent space from a textured indexed mesh (positions + normals + texcoords + indices)
|
* @brief computeTangents computes tangent space from a textured indexed mesh (positions + normals + texcoords + indices)
|
||||||
*/
|
*/
|
||||||
void computeTangents();
|
void computeTangents();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compute the bounding box of the mesh based on the 3D positions
|
* @brief computeBoundingBox computes the bounding box of the mesh based on the 3D positions
|
||||||
*/
|
*/
|
||||||
void computeBoundingBox(glm::vec3 &min, glm::vec3 &max);
|
void computeBoundingBox(glm::vec3 &min, glm::vec3 &max);
|
||||||
|
|
||||||
/*************************************************************/
|
|
||||||
/* SERIALISATION */
|
|
||||||
/*************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief serializeMesh can be used to save a mesh
|
|
||||||
* @return true if the mesh has succesfully been saved
|
|
||||||
*/
|
|
||||||
static bool serialize(Mesh* mesh, FILE *file);
|
|
||||||
|
|
||||||
bool serialize(FILE *file) { return serialize(this, file); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief deserializeMesh can be used to load a mesh
|
|
||||||
* @return the loaded mesh of NULL if a reading error has occured
|
|
||||||
*/
|
|
||||||
static Mesh* deserialize(FILE *file);
|
|
||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
/* ADVANCED CUSTOMISATION */
|
/* ADVANCED CUSTOMISATION */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
@ -253,19 +246,19 @@ public:
|
|||||||
unsigned int updateFlags();
|
unsigned int updateFlags();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string m_name;
|
std::string m_name; // yup
|
||||||
|
|
||||||
Material* material;
|
Material* material; // nop
|
||||||
bool isDoubleSided;
|
bool isDoubleSided; // yup
|
||||||
bool isBillboard;
|
bool isBillboard; // yup
|
||||||
bool isWireframe;
|
bool isWireframe; // yup
|
||||||
bool isShadowCaster;
|
bool isShadowCaster; // yup
|
||||||
float depth;
|
float depth; // yup
|
||||||
unsigned int m_flags;
|
unsigned int m_flags; // nop GL
|
||||||
|
|
||||||
GLenum primitive_type;
|
GLenum primitive_type; // yup
|
||||||
|
|
||||||
std::vector<Buffer*> buffers;
|
std::vector<Buffer*> buffers; // nop GL
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
// required buffer
|
// required buffer
|
||||||
@ -286,12 +279,12 @@ protected:
|
|||||||
NB_BUFFERS
|
NB_BUFFERS
|
||||||
};
|
};
|
||||||
|
|
||||||
int buffersId[NB_BUFFERS];
|
int buffersId[NB_BUFFERS]; // nop GL
|
||||||
|
|
||||||
void addBuffer(Buffer *b, int bufferType);
|
void addBuffer(Buffer *b, int bufferType);
|
||||||
void clearBuffers();
|
void clearBuffers();
|
||||||
|
|
||||||
GLuint vao;
|
GLuint vao; // nop GL
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESH_H
|
#endif // MESH_H
|
||||||
|
@ -97,11 +97,11 @@ int MeshGenerator::getEdge(int a, int b)
|
|||||||
vid = current->vertex;
|
vid = current->vertex;
|
||||||
else if(current->next == NULL)
|
else if(current->next == NULL)
|
||||||
{
|
{
|
||||||
vid = m_mesh->positions3D.size();
|
vid = m_mesh->m_positions3D.size();
|
||||||
// creating subdivision vertex
|
// creating subdivision vertex
|
||||||
|
|
||||||
// u/v sphériques, cohérents sur toute la sphère sauf des artefacts au niveau des u==0
|
// u/v sphériques, cohérents sur toute la sphère sauf des artefacts au niveau des u==0
|
||||||
glm::vec3 pos = glm::normalize((m_mesh->positions3D[a] + m_mesh->positions3D[b]) / 2.f);
|
glm::vec3 pos = glm::normalize((m_mesh->m_positions3D[a] + m_mesh->m_positions3D[b]) / 2.f);
|
||||||
float newU = (pos.x < 0 ? 1.5f : 1.f) + atan(pos.z/pos.x)/(2*M_PI);
|
float newU = (pos.x < 0 ? 1.5f : 1.f) + atan(pos.z/pos.x)/(2*M_PI);
|
||||||
float newV = acos(pos.y)/M_PI;
|
float newV = acos(pos.y)/M_PI;
|
||||||
// alternative, u/v moyennés :
|
// alternative, u/v moyennés :
|
||||||
@ -126,25 +126,25 @@ int MeshGenerator::getEdge(int a, int b)
|
|||||||
|
|
||||||
void MeshGenerator::subdivide()
|
void MeshGenerator::subdivide()
|
||||||
{
|
{
|
||||||
edges = new Edge[m_mesh->positions3D.size()-1];
|
edges = new Edge[m_mesh->m_positions3D.size()-1];
|
||||||
int nb_triangles = m_mesh->indices.size()/3;
|
int nb_triangles = m_mesh->m_indices.size()/3;
|
||||||
for(int j=0; j<nb_triangles; j++)
|
for(int j=0; j<nb_triangles; j++)
|
||||||
{
|
{
|
||||||
int vid[3];
|
int vid[3];
|
||||||
for(int k=0; k<3; k++)
|
for(int k=0; k<3; k++)
|
||||||
{
|
{
|
||||||
int idA = m_mesh->indices[j*3 + k];
|
int idA = m_mesh->m_indices[j*3 + k];
|
||||||
int idB = m_mesh->indices[j*3 + (k+1)%3];
|
int idB = m_mesh->m_indices[j*3 + (k+1)%3];
|
||||||
int a = idA < idB ? idA : idB;
|
int a = idA < idB ? idA : idB;
|
||||||
int b = idA > idB ? idA : idB;
|
int b = idA > idB ? idA : idB;
|
||||||
vid[k] = getEdge(a, b);
|
vid[k] = getEdge(a, b);
|
||||||
}
|
}
|
||||||
for(int k=0; k<3; k++)
|
for(int k=0; k<3; k++)
|
||||||
m_mesh->addTriangle(m_mesh->indices[j*3 + k], vid[k], vid[(k+2)%3]);
|
m_mesh->addTriangle(m_mesh->m_indices[j*3 + k], vid[k], vid[(k+2)%3]);
|
||||||
m_mesh->addTriangle(vid[0], vid[1], vid[2]);
|
m_mesh->addTriangle(vid[0], vid[1], vid[2]);
|
||||||
}
|
}
|
||||||
delete[](edges);
|
delete[](edges);
|
||||||
m_mesh->indices.erase(m_mesh->indices.begin(), m_mesh->indices.begin()+nb_triangles*3);
|
m_mesh->m_indices.erase(m_mesh->m_indices.begin(), m_mesh->m_indices.begin()+nb_triangles*3);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MeshGenerator::getVertexId(int i, int j, int height)
|
int MeshGenerator::getVertexId(int i, int j, int height)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user