#include "Defines.h" #include "render/loader/MobLoader.h" #include "render/loader/TextureLoader.h" #include #include #include #include namespace td { namespace render { TexturedModel::TexturedModel(GL::VertexArray&& vao, GL::Texture&& texture) { m_Vao = std::make_unique(std::move(vao)); m_Texture = std::make_unique(std::move(texture)); } TexturedModel::TexturedModel(TexturedModel&& other) { m_Vao = std::move(other.m_Vao); m_Texture = std::move(other.m_Texture); m_Positon = other.m_Positon; m_Color = other.m_Color; } namespace MobLoader { const static int POSITION_VERTEX_SIZE = 3; const static int TEXTURE_VERTEX_SIZE = 2; typedef Vec3f Vertex; typedef Vec2f TextureUV; typedef Vec3f Normal; struct Index { std::size_t vertexIndex; std::size_t textureIndex; std::size_t normalIndex; }; enum DataType : std::uint8_t { dt_Vertex, dt_Texture, dt_Normal, dt_Index, dt_None }; static DataType GetDataType(const std::string& type) { static const std::map Types = { {"v", dt_Vertex}, {"vt", dt_Texture}, {"vn", dt_Normal}, {"f", dt_Index} }; auto it = Types.find(type); return it != Types.end() ? it->second : dt_None; } static GL::VertexArray LoadMobVao(const std::string& objFile) { std::ifstream fileStream{ objFile }; std::string line; std::vector tempVertecies; std::vector tempTextureUvs; std::vector tempNormals; std::vector vertecies; std::vector textureUvs; std::vector normals; while (getline(fileStream, line)) { std::replace(line.begin(), line.end(), '/', ' '); std::stringstream ss; ss << line; std::string typeStr; ss >> typeStr; DataType dataType = GetDataType(typeStr); switch (dataType) { case dt_Vertex: { Vertex vertex; ss >> vertex.x; ss >> vertex.y; ss >> vertex.z; tempVertecies.push_back(vertex); break; } case dt_Texture: { TextureUV texture; ss >> texture.x; ss >> texture.y; tempTextureUvs.push_back(texture); break; } case dt_Normal: { Normal normal; ss >> normal.x; ss >> normal.y; ss >> normal.z; tempNormals.push_back(normal); break; } case dt_Index: { Index tempIndicies[4]; for (std::size_t i = 0; i < 4; i++){ ss >> tempIndicies[i].vertexIndex; ss >> tempIndicies[i].textureIndex; ss >> tempIndicies[i].normalIndex; } static const std::vector vertexOrder = {0, 1, 2, 0, 2, 3}; for(std::size_t i = 0; i < vertexOrder.size(); i++) { Index& index = tempIndicies[vertexOrder[i]]; std::size_t vertexIndex = index.vertexIndex - 1; std::size_t textureIndex = index.textureIndex - 1; std::size_t normalIndex = index.normalIndex - 1; Vertex vertex = tempVertecies[vertexIndex]; TextureUV texture = tempTextureUvs[textureIndex]; Normal normal = tempNormals[normalIndex]; vertecies.push_back(vertex.x); vertecies.push_back(vertex.y); vertecies.push_back(vertex.z); textureUvs.push_back(texture.x); textureUvs.push_back(1.0f - texture.y); normals.push_back(normal.x); normals.push_back(normal.y); normals.push_back(normal.z); } break; } default: break; } } GL::VertexBuffer positionVBO(vertecies, POSITION_VERTEX_SIZE); positionVBO.AddVertexAttribPointer(0, POSITION_VERTEX_SIZE, 0); GL::VertexBuffer textureVBO(textureUvs, TEXTURE_VERTEX_SIZE); textureVBO.AddVertexAttribPointer(1, TEXTURE_VERTEX_SIZE, 0); GL::VertexArray mobVao(vertecies.size() / POSITION_VERTEX_SIZE); // each pos = 1 color mobVao.Bind(); mobVao.BindVertexBuffer(positionVBO); mobVao.BindVertexBuffer(textureVBO); mobVao.Unbind(); return mobVao; } TexturedModel LoadMobModel(game::MobType mobType) { switch (mobType){ case game::MobType::Blaze: return {LoadMobVao("Assets/blaze.obj"), TextureLoader::LoadTexture("Assets/blaze.png")}; case game::MobType::Creeper: return {LoadMobVao("Assets/creeper.obj"), TextureLoader::LoadTexture("Assets/creeper.png")}; case game::MobType::Giant: return {LoadMobVao("Assets/giant.obj"), TextureLoader::LoadTexture("Assets/giant.png")}; case game::MobType::Pigman: return {LoadMobVao("Assets/zombified_piglin.obj"), TextureLoader::LoadTexture("Assets/zombified_piglin.png")}; case game::MobType::Silverfish: return {LoadMobVao("Assets/silverfish.obj"), TextureLoader::LoadTexture("Assets/silverfish.png")}; case game::MobType::Skeleton: return {LoadMobVao("Assets/skeleton.obj"), TextureLoader::LoadTexture("Assets/skeleton.png")}; case game::MobType::Slime: return {LoadMobVao("Assets/slime.obj"), TextureLoader::LoadTexture("Assets/slime.png")}; case game::MobType::Spider : return {LoadMobVao("Assets/spider.obj"), TextureLoader::LoadTexture("Assets/spider.png")}; case game::MobType::Witch : return {LoadMobVao("Assets/witch.obj"), TextureLoader::LoadTexture("Assets/witch.png")}; case game::MobType::Zombie : return {LoadMobVao("Assets/zombie.obj"), TextureLoader::LoadTexture("Assets/zombie.png")}; default: return {LoadMobVao("Assets/armor_stand.obj"), TextureLoader::LoadTexture("Assets/armor_stand.png")}; } } } // namespace MobLoader } // namespace render } // namespace td