skip not used materials
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ 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++) {
|
||||||
|
if (material->frames[i]->count > 0) {
|
||||||
frames.push_back(new MeshMaterialFrame(data, i, materialIndex));
|
frames.push_back(new MeshMaterialFrame(data, i, materialIndex));
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
@@ -53,6 +54,13 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
lastVertexCount = frames[i]->count;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
|||||||
Reference in New Issue
Block a user