Partially refactored model and mesh structures

dev
Tomasz Kapuściński 2022-03-11 19:49:03 +01:00
parent 7af32caec2
commit 4a16ee76a1
7 changed files with 203 additions and 22 deletions

View File

@ -4726,7 +4726,13 @@ int CEngine::AddStaticMesh(const std::string& key, const CModelMesh* mesh, const
if (it == m_staticMeshBaseObjects.end())
{
baseObjRank = CreateBaseObject();
AddBaseObjTriangles(baseObjRank, mesh->GetTriangles());
for (size_t i = 0; i < mesh->GetPartCount(); i++)
{
const auto& part = mesh->GetPart(i);
AddBaseObjTriangles(baseObjRank, part.GetVertices(), part.GetMaterial(), EngineTriangleType::TRIANGLES);
}
m_staticMeshBaseObjects[key] = baseObjRank;
}
else

View File

@ -79,7 +79,7 @@ void CModel::SetShadowSpot(const ModelShadowSpot& shadowSpot)
bool CModel::HasShadowSpot() const
{
return m_shadowSpot.is_initialized();
return m_shadowSpot.has_value();
}
const std::vector<ModelCrashSphere>& CModel::GetCrashSpheres() const
@ -109,7 +109,7 @@ void CModel::SetCameraCollisionSphere(const Math::Sphere& sphere)
bool CModel::HasCameraCollisionSphere() const
{
return m_cameraCollisionSphere.is_initialized();
return m_cameraCollisionSphere.has_value();
}
} // namespace Gfx

View File

@ -28,7 +28,7 @@
#include <map>
#include <string>
#include <vector>
#include <boost/optional.hpp>
#include <optional>
namespace Gfx
{
@ -75,8 +75,8 @@ public:
private:
std::map<std::string, CModelMesh> m_meshes;
std::vector<ModelCrashSphere> m_crashSpheres;
boost::optional<ModelShadowSpot> m_shadowSpot;
boost::optional<Math::Sphere> m_cameraCollisionSphere;
std::optional<ModelShadowSpot> m_shadowSpot;
std::optional<Math::Sphere> m_cameraCollisionSphere;
};
} // namespace Gfx

View File

@ -451,7 +451,9 @@ void ModelInput::ReadOldModel(CModel &model, std::istream &stream)
}
CModelMesh mesh;
mesh.SetTriangles(std::move(triangles));
for (const auto& triangle : triangles)
mesh.AddTriangle(triangle);
model.AddMesh("main", std::move(mesh));
}

View File

@ -22,24 +22,101 @@
namespace Gfx
{
CModelPart::CModelPart(const Material& material)
: m_material(material) {}
const Material& CModelPart::GetMaterial() const
{
return m_material;
}
bool CModelPart::IsIndexed() const
{
return !m_indices.empty();
}
size_t CModelPart::GetVertexCount() const
{
return m_vertices.size();
}
const std::vector<Vertex3D>& CModelPart::GetVertices() const
{
return m_vertices;
}
size_t CModelPart::GetIndexCount() const
{
return m_indices.size();
}
const std::vector<unsigned int>& CModelPart::GetIndices() const
{
return m_indices;
}
void CModelPart::AddVertex(const Vertex3D& vertex)
{
m_vertices.push_back(vertex);
}
void CModelPart::AddIndex(unsigned int index)
{
m_indices.push_back(index);
}
void CModelMesh::AddTriangle(const ModelTriangle& triangle)
{
m_triangles.push_back(triangle);
for (auto& part : m_parts)
{
if (part.GetMaterial() == triangle.material)
{
part.AddVertex(triangle.p1);
part.AddVertex(triangle.p2);
part.AddVertex(triangle.p3);
return;
}
}
CModelPart part(triangle.material);
part.AddVertex(triangle.p1);
part.AddVertex(triangle.p2);
part.AddVertex(triangle.p3);
m_parts.emplace_back(part);
}
void CModelMesh::SetTriangles(std::vector<ModelTriangle>&& triangles)
void CModelMesh::AddTriangle(const Triangle& triangle, const Material& material)
{
m_triangles = triangles;
for (auto& part : m_parts)
{
if (part.GetMaterial() == material)
{
part.AddVertex(triangle.p1);
part.AddVertex(triangle.p2);
part.AddVertex(triangle.p3);
return;
}
}
CModelPart part(material);
part.AddVertex(triangle.p1);
part.AddVertex(triangle.p2);
part.AddVertex(triangle.p3);
m_parts.emplace_back(part);
}
const std::vector<ModelTriangle>& CModelMesh::GetTriangles() const
size_t CModelMesh::GetPartCount() const
{
return m_triangles;
return m_parts.size();
}
int CModelMesh::GetTriangleCount() const
const CModelPart& CModelMesh::GetPart(size_t index) const
{
return m_triangles.size();
return m_parts[index];
}
const glm::vec3& CModelMesh::GetPosition() const
@ -82,4 +159,44 @@ void CModelMesh::SetParent(const std::string& parent)
m_parent = parent;
}
std::vector<ModelTriangle> CModelMesh::GetTriangles() const
{
std::vector<ModelTriangle> triangles;
for (const auto& part : m_parts)
{
if (part.IsIndexed())
{
const auto& vertices = part.GetVertices();
const auto& indices = part.GetIndices();
for (size_t i = 0; i < indices.size() - 2; i += 3)
{
triangles.push_back({
vertices[indices[i]],
vertices[indices[i + 1]],
vertices[indices[i + 2]],
part.GetMaterial()
});
}
}
else
{
const auto& vertices = part.GetVertices();
for (size_t i = 0; i < vertices.size() - 2; i += 3)
{
triangles.push_back({
vertices[i],
vertices[i + 1],
vertices[i + 2],
part.GetMaterial()
});
}
}
}
return triangles;
}
} // namespace Gfx

View File

@ -26,6 +26,44 @@
namespace Gfx
{
/**
* \class CModelPart
* \brief Part of mesh with a common material
*/
class CModelPart
{
public:
//! Creates new part for given material
CModelPart(const Material& material);
//! Returns this part's material
const Material& GetMaterial() const;
//! Returns true if this part is indexed
bool IsIndexed() const;
//! Returns the number of vertices in this part
size_t GetVertexCount() const;
//! Returns the vertices in this part
const std::vector<Vertex3D>& GetVertices() const;
//! Returns the number of indices in this part
size_t GetIndexCount() const;
//! Returns the indices in this part
const std::vector<unsigned int>& GetIndices() const;
//! Adds a vertex
void AddVertex(const Vertex3D& vertex);
//! Adds an index
void AddIndex(unsigned int index);
private:
//! Material
Material m_material;
//! Vertices
std::vector<Vertex3D> m_vertices;
//! Indices
std::vector<unsigned int> m_indices;
};
/**
* \class CModelMesh
* \brief Mesh data saved in model file
@ -35,12 +73,13 @@ class CModelMesh
public:
//! Adds a new triangle
void AddTriangle(const ModelTriangle& triangle);
//! Sets the list of triangles
void SetTriangles(std::vector<ModelTriangle> &&triangles);
//! Returns the list of triangles
const std::vector<ModelTriangle>& GetTriangles() const;
//! Returns number of triangles
int GetTriangleCount() const;
//! Adds a new triangle
void AddTriangle(const Triangle& triangle, const Material& material);
//! Returns the number of parts
size_t GetPartCount() const;
//! Returns a part with given index
const CModelPart& GetPart(size_t index) const;
//! Returns the mesh position
const glm::vec3& GetPosition() const;
@ -62,8 +101,11 @@ public:
//! Sets the name of parent mesh
void SetParent(const std::string& parent);
//! Returns all model triangles of this mesh
std::vector<ModelTriangle> GetTriangles() const;
private:
std::vector<ModelTriangle> m_triangles;
std::vector<CModelPart> m_parts;
glm::vec3 m_position;
glm::vec3 m_rotation;
glm::vec3 m_scale;

View File

@ -25,11 +25,25 @@
namespace Gfx
{
/**
* \struct Triangle
* \brief A single triangle
*/
struct Triangle
{
//! 1st vertex
Vertex3D p1;
//! 2nd vertex
Vertex3D p2;
//! 3rd vertex
Vertex3D p3;
};
/**
* \struct ModelTriangle
* \brief A single triangle in mesh as saved in model file
*/
struct ModelTriangle
struct [[deprecated]] ModelTriangle
{
//! 1st vertex
Vertex3D p1;