ADD: Support multiple materials per object
@ -9,4 +9,4 @@ Ke 0.000000 0.000000 0.000000
|
|||||||
Ni 1.500000
|
Ni 1.500000
|
||||||
d 1.000000
|
d 1.000000
|
||||||
illum 2
|
illum 2
|
||||||
map_Kd /home/sebastian/Downloads/textures/Image_0.002.webp
|
map_Kd stone_mason.png
|
||||||
|
|||||||
32
assets/buildings/stone_mason/stone_masonobj_full.mtl
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Blender 5.0.1 MTL File: 'Untitled.blend'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl Cobblestone_tjemdayjw
|
||||||
|
Ns 0.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd textures/tjemdayjw_4K_Albedo_LOD7.jpg
|
||||||
|
|
||||||
|
newmtl Cobblestone_tjemdbyiw
|
||||||
|
Ns 0.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd textures/tjemdbyiw_4K_Albedo_LOD6.jpg
|
||||||
|
|
||||||
|
newmtl Material_0.002
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
||||||
|
map_Kd textures/stone_mason.png
|
||||||
533060
assets/buildings/stone_mason/stone_masonobj_full.obj
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
assets/buildings/stone_mason/textures/stone_mason.png
Normal file
|
After Width: | Height: | Size: 4.0 MiB |
BIN
assets/buildings/stone_mason/textures/tjemdayjw_4K_AO.jpg
Normal file
|
After Width: | Height: | Size: 5.6 MiB |
|
After Width: | Height: | Size: 8.5 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 11 MiB |
BIN
assets/buildings/stone_mason/textures/tjemdayjw_4K_Roughness.jpg
Normal file
|
After Width: | Height: | Size: 3.8 MiB |
BIN
assets/buildings/stone_mason/textures/tjemdbyiw_4K_AO.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
|
After Width: | Height: | Size: 7.8 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 11 MiB |
BIN
assets/buildings/stone_mason/textures/tjemdbyiw_4K_Roughness.jpg
Normal file
|
After Width: | Height: | Size: 4.1 MiB |
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#define TINYOBJLOADER_IMPLEMENTATION
|
#define TINYOBJLOADER_IMPLEMENTATION
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "tiny_obj_loader.h"
|
#include "tiny_obj_loader.h"
|
||||||
|
|
||||||
@ -14,21 +16,28 @@ std::shared_ptr<TexturedModel> OBJLoader::loadModel(const std::string &modelPath
|
|||||||
std::vector<tinyobj::shape_t> shapes;
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
std::vector<tinyobj::material_t> materials;
|
std::vector<tinyobj::material_t> materials;
|
||||||
std::string warn, err;
|
std::string warn, err;
|
||||||
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, modelPath.c_str())) {
|
std::string baseDir = std::filesystem::path(modelPath).parent_path().string();
|
||||||
throw std::runtime_error(warn + err);
|
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, modelPath.c_str(), baseDir.c_str());
|
||||||
|
|
||||||
|
if (!warn.empty()) {
|
||||||
|
std::cout << "OBJ Loader warning: " << warn << std::endl;
|
||||||
|
}
|
||||||
|
if (!err.empty()) {
|
||||||
|
std::cerr << "OBJ Loader error: " << err << std::endl;
|
||||||
|
}
|
||||||
|
if (!ret) {
|
||||||
|
throw std::runtime_error("Failed to load OBJ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, modelPath.c_str())) {
|
std::vector<SubModel> subModels;
|
||||||
throw std::runtime_error("Failed to load OBJ: " + warn + err);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float> vertices;
|
|
||||||
std::vector<float> normals;
|
|
||||||
std::vector<float> uvs;
|
|
||||||
std::vector<int> indices;
|
|
||||||
|
|
||||||
int indexOffset = 0;
|
|
||||||
for (const auto& shape : shapes) {
|
for (const auto& shape : shapes) {
|
||||||
|
std::vector<float> vertices;
|
||||||
|
std::vector<float> normals;
|
||||||
|
std::vector<float> uvs;
|
||||||
|
std::vector<int> indices;
|
||||||
|
int indexOffset = 0;
|
||||||
for (const auto& index : shape.mesh.indices) {
|
for (const auto& index : shape.mesh.indices) {
|
||||||
// Vertex-Position
|
// Vertex-Position
|
||||||
vertices.push_back(attrib.vertices[3*index.vertex_index + 0]);
|
vertices.push_back(attrib.vertices[3*index.vertex_index + 0]);
|
||||||
@ -52,10 +61,30 @@ std::shared_ptr<TexturedModel> OBJLoader::loadModel(const std::string &modelPath
|
|||||||
indices.push_back(indexOffset);
|
indices.push_back(indexOffset);
|
||||||
indexOffset++;
|
indexOffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RawModel rawModel = loader.loadToVAO(vertices, normals, uvs, indices);
|
||||||
|
|
||||||
|
std::shared_ptr<ModelTexture> texture = nullptr;
|
||||||
|
if (!materials.empty() && !shape.mesh.material_ids.empty()) {
|
||||||
|
int matID = shape.mesh.material_ids[0];
|
||||||
|
if (matID >= 0 && matID < static_cast<int>(materials.size())) {
|
||||||
|
tinyobj::material_t &mat = materials[matID];
|
||||||
|
if (!mat.diffuse_texname.empty()) {
|
||||||
|
std::string texFile = mat.diffuse_texname;
|
||||||
|
std::filesystem::path fullTexPath = std::filesystem::path(baseDir) / std::filesystem::path(texFile);
|
||||||
|
texture = std::make_shared<ModelTexture>(loader.loadTextureFromFile(fullTexPath.string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!texture) {
|
||||||
|
texture = std::make_shared<ModelTexture>(loader.loadTextureFromFile(texturePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
subModels.emplace_back(
|
||||||
|
std::make_shared<RawModel>(rawModel), texture
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
RawModel rawModel = loader.loadToVAO(vertices, normals, uvs, indices);
|
return std::make_shared<TexturedModel>(subModels);
|
||||||
ModelTexture modelTexture = loader.loadTextureFromFile(texturePath);
|
|
||||||
TexturedModel texturedModel = TexturedModel(std::make_shared<RawModel>(rawModel), std::make_shared<ModelTexture>(modelTexture));
|
|
||||||
return std::make_shared<TexturedModel>(texturedModel);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,6 +64,13 @@ void GameLayer::onAttach()
|
|||||||
EntityID entityID = entityManager->createEntity();
|
EntityID entityID = entityManager->createEntity();
|
||||||
entityManager->addComponent(entityID, transformComponent);
|
entityManager->addComponent(entityID, transformComponent);
|
||||||
entityManager->addComponent(entityID, modelComponent);*/
|
entityManager->addComponent(entityID, modelComponent);*/
|
||||||
|
|
||||||
|
auto test = AssetManager::loadModel("test", "assets/buildings/stone_mason/stone_masonobj_full.obj", "assets/buildings/stone_mason/textures/stone_mason.png", loader);
|
||||||
|
auto transformComponent = std::make_shared<TransformComponent>(glm::vec3(0,0,0), glm::vec3(0), 1.f);
|
||||||
|
auto modelComponent = std::make_shared<ModelComponent>(test);
|
||||||
|
EntityID entityID = entityManager->createEntity();
|
||||||
|
entityManager->addComponent(entityID, transformComponent);
|
||||||
|
entityManager->addComponent(entityID, modelComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameLayer::onDetach()
|
void GameLayer::onDetach()
|
||||||
|
|||||||