skip not used materials

This commit is contained in:
h4570
2022-08-10 22:42:27 +02:00
parent 0a2d19b2d0
commit 5f5f28b3fb
6 changed files with 83 additions and 65 deletions
+1
View File
@@ -55,6 +55,7 @@ Terrain::~Terrain() {
void Terrain::allocateOptions() { void Terrain::allocateOptions() {
options = new StaPipOptions(); options = new StaPipOptions();
options->frustumCulling = Tyra::PipelineFrustumCulling_None;
options->shadingType = Tyra::TyraShadingGouraud; options->shadingType = Tyra::TyraShadingGouraud;
options->blendingEnabled = true; options->blendingEnabled = true;
options->antiAliasingEnabled = false; options->antiAliasingEnabled = false;
@@ -29,6 +29,11 @@ struct ObjLoaderOptions {
ObjLoaderAnimationOptions animation; ObjLoaderAnimationOptions animation;
}; };
struct MaterialVertexCount {
size_t materialId;
int count;
};
/** Class responsible for loading & parsing obj files */ /** Class responsible for loading & parsing obj files */
class ObjLoader : public Loader { class ObjLoader : public Loader {
public: public:
@@ -45,13 +50,12 @@ class ObjLoader : public Loader {
void addOutputMaterialsAndFrames( void addOutputMaterialsAndFrames(
MeshBuilderData* output, const tinyobj::attrib_t& attrib, MeshBuilderData* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials, const std::vector<tinyobj::material_t>& materials, const u16& framesCount,
const u16& framesCount); std::vector<MaterialVertexCount>& materialVertexCounts);
void scan(MeshBuilderData* output, const tinyobj::attrib_t& attrib, std::vector<MaterialVertexCount> scan(
const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials, const std::vector<tinyobj::material_t>& materials);
const u16& frameIndex);
void importFrame(MeshBuilderData* output, const tinyobj::attrib_t& attrib, void importFrame(MeshBuilderData* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::shape_t>& shapes,
+42 -48
View File
@@ -92,12 +92,11 @@ MeshBuilderData* ObjLoader::load(const char* fullpath,
"mtlib in obj file"); "mtlib in obj file");
if (i == 1) { if (i == 1) {
auto scanResult = scan(shapes, materials);
addOutputMaterialsAndFrames(result, attrib, shapes, materials, addOutputMaterialsAndFrames(result, attrib, shapes, materials,
options.animation.count); options.animation.count, scanResult);
} }
scan(result, attrib, shapes, materials, i - 1);
importFrame(result, attrib, shapes, materials, i - 1, options.scale, importFrame(result, attrib, shapes, materials, i - 1, options.scale,
options.flipUVs, options.animation.count); options.flipUVs, options.animation.count);
} }
@@ -105,10 +104,38 @@ MeshBuilderData* ObjLoader::load(const char* fullpath,
return result; return result;
} }
std::vector<MaterialVertexCount> ObjLoader::scan(
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials) {
std::vector<MaterialVertexCount> result;
for (size_t i = 0; i < materials.size(); i++) {
MaterialVertexCount counter = {i, 0};
result.push_back(counter);
}
for (size_t s = 0; s < shapes.size(); s++) {
const auto& mesh = shapes[s].mesh;
for (size_t f = 0; f < mesh.num_face_vertices.size(); f++) {
const auto& materialId = mesh.material_ids[f];
const auto& vertCountPerFace = size_t(mesh.num_face_vertices[f]);
TYRA_ASSERT(vertCountPerFace == 3,
"TinyObjLoader should triangulate mesh, internal error!");
result[materialId].count += vertCountPerFace;
}
}
return result;
}
void ObjLoader::addOutputMaterialsAndFrames( void ObjLoader::addOutputMaterialsAndFrames(
MeshBuilderData* output, const tinyobj::attrib_t& attrib, MeshBuilderData* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials, const u16& framesCount) { const std::vector<tinyobj::material_t>& materials, const u16& framesCount,
std::vector<MaterialVertexCount>& materialVertexCounts) {
if (attrib.texcoords.size()) output->textureCoordsEnabled = true; if (attrib.texcoords.size()) output->textureCoordsEnabled = true;
if (attrib.normals.size()) output->normalsEnabled = true; if (attrib.normals.size()) output->normalsEnabled = true;
@@ -129,6 +156,17 @@ void ObjLoader::addOutputMaterialsAndFrames(
for (size_t j = 0; j < framesCount; j++) { for (size_t j = 0; j < framesCount; j++) {
auto* frame = new MeshBuilderMaterialFrameData(); auto* frame = new MeshBuilderMaterialFrameData();
const auto& counter = materialVertexCounts[i];
frame->count = counter.count;
frame->vertices = new Vec4[counter.count];
if (output->textureCoordsEnabled)
frame->textureCoords = new Vec4[counter.count];
if (output->normalsEnabled) frame->normals = new Vec4[counter.count];
material->frames.push_back(frame); material->frames.push_back(frame);
} }
@@ -136,50 +174,6 @@ void ObjLoader::addOutputMaterialsAndFrames(
} }
} }
void ObjLoader::scan(MeshBuilderData* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials,
const u16& frameIndex) {
struct MaterialVertexCount {
size_t materialId;
int count;
};
std::vector<MaterialVertexCount> materialVertexCounts;
for (size_t i = 0; i < materials.size(); i++) {
MaterialVertexCount counter = {i, 0};
materialVertexCounts.push_back(counter);
}
for (size_t s = 0; s < shapes.size(); s++) {
const auto& mesh = shapes[s].mesh;
for (size_t f = 0; f < mesh.num_face_vertices.size(); f++) {
const auto& materialId = mesh.material_ids[f];
const auto& vertCountPerFace = size_t(mesh.num_face_vertices[f]);
TYRA_ASSERT(vertCountPerFace == 3,
"TinyObjLoader should triangulate mesh, internal error!");
materialVertexCounts[materialId].count += vertCountPerFace;
}
}
for (size_t i = 0; i < materials.size(); i++) {
const auto& counter = materialVertexCounts[i];
auto* outFrame = output->materials[i]->frames[frameIndex];
outFrame->count = counter.count;
outFrame->vertices = new Vec4[counter.count];
if (output->textureCoordsEnabled)
outFrame->textureCoords = new Vec4[counter.count];
if (output->normalsEnabled) outFrame->normals = new Vec4[counter.count];
}
}
void ObjLoader::importFrame(MeshBuilderData* output, void ObjLoader::importFrame(MeshBuilderData* output,
const tinyobj::attrib_t& attrib, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::shape_t>& shapes,
+9 -1
View File
@@ -20,7 +20,15 @@ Mesh::Mesh(const MeshBuilderData& data) {
"Materials count must be greater than 0"); "Materials count must be greater than 0");
for (u32 i = 0; i < data.materials.size(); i++) { for (u32 i = 0; i < data.materials.size(); i++) {
materials.push_back(new MeshMaterial(data, i)); auto* material = new MeshMaterial(data, i);
if (material->frames.size() == 0) {
TYRA_WARN("Found empty material: ", material->name, ". Skipping...");
delete material;
continue;
}
materials.push_back(material);
} }
isMother = true; isMother = true;
+14 -6
View File
@@ -45,14 +45,22 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data,
u32 lastVertexCount = 0; u32 lastVertexCount = 0;
for (u32 i = 0; i < material->frames.size(); i++) { for (u32 i = 0; i < material->frames.size(); i++) {
frames.push_back(new MeshMaterialFrame(data, i, materialIndex)); if (material->frames[i]->count > 0) {
frames.push_back(new MeshMaterialFrame(data, i, materialIndex));
if (i > 0) { if (i > 0) {
TYRA_ASSERT(frames[i]->count == lastVertexCount, TYRA_ASSERT(frames[i]->count == lastVertexCount,
"Vertex count must be the same for all frames"); "Vertex count must be the same for all frames");
}
lastVertexCount = frames[i]->count;
} else { // We will not use it, lets clean it up
auto* frame = material->frames[i];
if (frame->vertices != nullptr) delete[] frame->vertices;
if (frame->normals != nullptr) delete[] frame->normals;
if (frame->textureCoords != nullptr) delete[] frame->textureCoords;
if (frame->colors != nullptr) delete[] frame->colors;
} }
lastVertexCount = frames[i]->count;
} }
isMother = true; isMother = true;
@@ -21,17 +21,20 @@ namespace Tyra {
MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data, MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data,
const u32& frameIndex, const u32& frameIndex,
const u32& materialIndex) { const u32& materialIndex) {
auto* material = data.materials[materialIndex];
TYRA_ASSERT(materialIndex < data.materials.size(), "Provided index \"", TYRA_ASSERT(materialIndex < data.materials.size(), "Provided index \"",
materialIndex, "\" is out of range"); materialIndex, "\" is out of range");
TYRA_ASSERT(frameIndex < data.materials[materialIndex]->frames.size(), TYRA_ASSERT(frameIndex < material->frames.size(), "Provided index \"",
"Provided index \"", frameIndex, "\" is out of range"); frameIndex, "\" is out of range");
id = rand() % 1000000; id = rand() % 1000000;
auto* frame = data.materials[materialIndex]->frames[frameIndex]; auto* frame = material->frames[frameIndex];
TYRA_ASSERT(frame->count > 0, "Vertex count must be greater than 0"); TYRA_ASSERT(frame->count > 0, "Vertex count must be greater than 0",
"Material name: ", material->name);
TYRA_ASSERT(frame->vertices != nullptr, "Vertex array can't be null"); TYRA_ASSERT(frame->vertices != nullptr, "Vertex array can't be null");
TYRA_ASSERT(!data.normalsEnabled || frame->normals != nullptr, TYRA_ASSERT(!data.normalsEnabled || frame->normals != nullptr,
"Normal array can't be null"); "Normal array can't be null");