updated main header
This commit is contained in:
@@ -5,47 +5,53 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
std::vector<Triangle> ObjLoader::load_obj(const std::string& obj_filepath,
|
std::vector<Triangle> ObjLoader::load_obj(const std::string &obj_filepath,
|
||||||
Renderer& renderer)
|
Renderer &renderer)
|
||||||
{
|
{
|
||||||
std::vector<Triangle> triangles;
|
std::vector<Triangle> triangles;
|
||||||
std::vector<Vec3> vertices;
|
std::vector<Vec3> vertices;
|
||||||
std::vector<Vec2> uvs;
|
std::vector<Vec2> uvs;
|
||||||
std::vector<Vec3> normals;
|
std::vector<Vec3> normals;
|
||||||
std::map<std::string, Texture> material_textures; // Maps material names to textures
|
std::map<std::string, Texture> material_textures;
|
||||||
std::string current_material;
|
std::string current_material;
|
||||||
std::string mtl_filepath;
|
std::string mtl_filepath;
|
||||||
|
|
||||||
// Helper to parse MTL file
|
auto parse_mtl = [&](const std::string &mtl_path)
|
||||||
auto parse_mtl = [&](const std::string& mtl_path) {
|
{
|
||||||
std::ifstream mtl_file(mtl_path);
|
std::ifstream mtl_file(mtl_path);
|
||||||
if (!mtl_file.is_open()) {
|
if (!mtl_file.is_open())
|
||||||
// Silently skip if MTL file cannot be opened
|
{
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line, current_mtl;
|
std::string line, current_mtl;
|
||||||
while (std::getline(mtl_file, line)) {
|
while (std::getline(mtl_file, line))
|
||||||
|
{
|
||||||
std::istringstream iss(line);
|
std::istringstream iss(line);
|
||||||
std::string token;
|
std::string token;
|
||||||
iss >> token;
|
iss >> token;
|
||||||
|
|
||||||
if (token == "newmtl") {
|
if (token == "newmtl")
|
||||||
|
{
|
||||||
iss >> current_mtl;
|
iss >> current_mtl;
|
||||||
}
|
}
|
||||||
else if (token == "map_Kd") {
|
else if (token == "map_Kd")
|
||||||
|
{
|
||||||
std::string texture_path;
|
std::string texture_path;
|
||||||
std::getline(iss, texture_path);
|
std::getline(iss, texture_path);
|
||||||
texture_path.erase(0, texture_path.find_first_not_of(" \t"));
|
texture_path.erase(0, texture_path.find_first_not_of(" \t"));
|
||||||
|
|
||||||
// Construct full texture path relative to MTL directory
|
|
||||||
std::filesystem::path mtl_dir = std::filesystem::path(mtl_path).parent_path();
|
std::filesystem::path mtl_dir = std::filesystem::path(mtl_path).parent_path();
|
||||||
std::filesystem::path tex_path = mtl_dir / texture_path;
|
std::filesystem::path tex_path = mtl_dir / texture_path;
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
material_textures[current_mtl] = renderer.load_texture(tex_path.string());
|
material_textures[current_mtl] = renderer.load_texture(tex_path.string());
|
||||||
} catch (const std::exception& e) {
|
}
|
||||||
// Fallback to default texture (id=0) if loading fails
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
|
||||||
material_textures[current_mtl] = Texture(0, 0, 0);
|
material_textures[current_mtl] = Texture(0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,78 +59,81 @@ std::vector<Triangle> ObjLoader::load_obj(const std::string& obj_filepath,
|
|||||||
mtl_file.close();
|
mtl_file.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Open and parse OBJ file
|
|
||||||
std::ifstream obj_file(obj_filepath);
|
std::ifstream obj_file(obj_filepath);
|
||||||
if (!obj_file.is_open()) {
|
if (!obj_file.is_open())
|
||||||
|
{
|
||||||
throw std::runtime_error("Failed to open OBJ file: " + obj_filepath);
|
throw std::runtime_error("Failed to open OBJ file: " + obj_filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path obj_dir = std::filesystem::path(obj_filepath).parent_path();
|
std::filesystem::path obj_dir = std::filesystem::path(obj_filepath).parent_path();
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(obj_file, line)) {
|
while (std::getline(obj_file, line))
|
||||||
|
{
|
||||||
std::istringstream iss(line);
|
std::istringstream iss(line);
|
||||||
std::string token;
|
std::string token;
|
||||||
iss >> token;
|
iss >> token;
|
||||||
|
|
||||||
if (token == "v") {
|
if (token == "v")
|
||||||
|
{
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
iss >> x >> y >> z;
|
iss >> x >> y >> z;
|
||||||
vertices.emplace_back(x, y, z);
|
vertices.emplace_back(x, y, z);
|
||||||
}
|
}
|
||||||
else if (token == "vt") {
|
else if (token == "vt")
|
||||||
|
{
|
||||||
float u, v;
|
float u, v;
|
||||||
iss >> u >> v;
|
iss >> u >> v;
|
||||||
uvs.emplace_back(u, v);
|
uvs.emplace_back(u, v);
|
||||||
}
|
}
|
||||||
else if (token == "vn") {
|
else if (token == "vn")
|
||||||
|
{
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
iss >> x >> y >> z;
|
iss >> x >> y >> z;
|
||||||
normals.emplace_back(x, y, z);
|
normals.emplace_back(x, y, z);
|
||||||
}
|
}
|
||||||
else if (token == "f") {
|
else if (token == "f")
|
||||||
std::vector<std::tuple<int, int, int>> face_vertices; // v/vt/vn indices
|
{
|
||||||
|
std::vector<std::tuple<int, int, int>> face_vertices;
|
||||||
std::string vertex;
|
std::string vertex;
|
||||||
while (iss >> vertex) {
|
while (iss >> vertex)
|
||||||
|
{
|
||||||
int v_idx = 0, vt_idx = 0, vn_idx = 0;
|
int v_idx = 0, vt_idx = 0, vn_idx = 0;
|
||||||
std::sscanf(vertex.c_str(), "%d/%d/%d", &v_idx, &vt_idx, &vn_idx);
|
std::sscanf(vertex.c_str(), "%d/%d/%d", &v_idx, &vt_idx, &vn_idx);
|
||||||
face_vertices.emplace_back(v_idx - 1, vt_idx - 1, vn_idx - 1); // Convert to 0-based
|
face_vertices.emplace_back(v_idx - 1, vt_idx - 1, vn_idx - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triangulate if necessary (e.g., for quads)
|
for (size_t i = 1; i < face_vertices.size() - 1; ++i)
|
||||||
for (size_t i = 1; i < face_vertices.size() - 1; ++i) {
|
{
|
||||||
Triangle tri;
|
Triangle tri;
|
||||||
auto [v0, vt0, vn0] = face_vertices[0];
|
auto [v0, vt0, vn0] = face_vertices[0];
|
||||||
auto [v1, vt1, vn1] = face_vertices[i];
|
auto [v1, vt1, vn1] = face_vertices[i];
|
||||||
auto [v2, vt2, vn2] = face_vertices[i + 1];
|
auto [v2, vt2, vn2] = face_vertices[i + 1];
|
||||||
|
|
||||||
// Assign vertices
|
|
||||||
tri.v0 = vertices[v0];
|
tri.v0 = vertices[v0];
|
||||||
tri.v1 = vertices[v1];
|
tri.v1 = vertices[v1];
|
||||||
tri.v2 = vertices[v2];
|
tri.v2 = vertices[v2];
|
||||||
|
|
||||||
// Assign UVs (use default if not specified)
|
|
||||||
tri.uv0 = vt0 >= 0 && vt0 < uvs.size() ? uvs[vt0] : Vec2(0, 0);
|
tri.uv0 = vt0 >= 0 && vt0 < uvs.size() ? uvs[vt0] : Vec2(0, 0);
|
||||||
tri.uv1 = vt1 >= 0 && vt1 < uvs.size() ? uvs[vt1] : Vec2(0, 0);
|
tri.uv1 = vt1 >= 0 && vt1 < uvs.size() ? uvs[vt1] : Vec2(0, 0);
|
||||||
tri.uv2 = vt2 >= 0 && vt2 < uvs.size() ? uvs[vt2] : Vec2(0, 0);
|
tri.uv2 = vt2 >= 0 && vt2 < uvs.size() ? uvs[vt2] : Vec2(0, 0);
|
||||||
|
|
||||||
// Assign default color
|
|
||||||
tri.color = Color(255, 255, 255);
|
tri.color = Color(255, 255, 255);
|
||||||
|
|
||||||
// Assign texture based on current material
|
tri.texture = material_textures.count(current_material) ? material_textures[current_material] : Texture(0, 0, 0);
|
||||||
tri.texture = material_textures.count(current_material) ?
|
|
||||||
material_textures[current_material] : Texture(0, 0, 0);
|
|
||||||
|
|
||||||
triangles.push_back(tri);
|
triangles.push_back(tri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (token == "mtllib") {
|
else if (token == "mtllib")
|
||||||
|
{
|
||||||
std::string mtl_name;
|
std::string mtl_name;
|
||||||
iss >> mtl_name;
|
iss >> mtl_name;
|
||||||
mtl_filepath = (obj_dir / mtl_name).string();
|
mtl_filepath = (obj_dir / mtl_name).string();
|
||||||
parse_mtl(mtl_filepath);
|
parse_mtl(mtl_filepath);
|
||||||
}
|
}
|
||||||
else if (token == "usemtl") {
|
else if (token == "usemtl")
|
||||||
|
{
|
||||||
iss >> current_material;
|
iss >> current_material;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <renderer.h>
|
#include <renderer.h>
|
||||||
#include <mesh.h>
|
#include <obj_loader.h>
|
||||||
#include <time_manager.h>
|
#include <time_manager.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
@@ -2,31 +2,32 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
Time::Time()
|
Time::Time()
|
||||||
: lastFrameTime(glfwGetTime())
|
: lastFrameTime(glfwGetTime()), currentFrameTime(lastFrameTime), deltaTime(0), elapsedTime(0.0f)
|
||||||
, currentFrameTime(lastFrameTime)
|
{
|
||||||
, deltaTime(0)
|
|
||||||
, elapsedTime(0.0f) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Time::Update() {
|
void Time::Update()
|
||||||
|
{
|
||||||
currentFrameTime = glfwGetTime();
|
currentFrameTime = glfwGetTime();
|
||||||
float deltaTimeSeconds = static_cast<float>(currentFrameTime - lastFrameTime);
|
float deltaTimeSeconds = static_cast<float>(currentFrameTime - lastFrameTime);
|
||||||
|
|
||||||
// Store delta time in fixed-point and update elapsed time
|
|
||||||
deltaTime = SecondsToFixed(deltaTimeSeconds);
|
deltaTime = SecondsToFixed(deltaTimeSeconds);
|
||||||
elapsedTime += deltaTimeSeconds;
|
elapsedTime += deltaTimeSeconds;
|
||||||
|
|
||||||
lastFrameTime = currentFrameTime;
|
lastFrameTime = currentFrameTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Time::GetDeltaTime() const {
|
int32_t Time::GetDeltaTime() const
|
||||||
|
{
|
||||||
return deltaTime;
|
return deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Time::GetElapsedTime() const {
|
float Time::GetElapsedTime() const
|
||||||
|
{
|
||||||
return elapsedTime;
|
return elapsedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Time::SecondsToFixed(float seconds) const {
|
int32_t Time::SecondsToFixed(float seconds) const
|
||||||
|
{
|
||||||
return static_cast<int32_t>(seconds * FIXED_POINT_SCALE);
|
return static_cast<int32_t>(seconds * FIXED_POINT_SCALE);
|
||||||
}
|
}
|
||||||
@@ -3,30 +3,26 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
class Time {
|
class Time
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Time();
|
Time();
|
||||||
|
|
||||||
// Update time and calculate delta time (call each frame)
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
// Get delta time in seconds (fixed-point representation)
|
|
||||||
int32_t GetDeltaTime() const;
|
int32_t GetDeltaTime() const;
|
||||||
|
|
||||||
// Get total elapsed time in seconds
|
|
||||||
float GetElapsedTime() const;
|
float GetElapsedTime() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Fixed-point scale for PS1-style precision
|
static constexpr int32_t FIXED_POINT_SCALE = 4096;
|
||||||
static constexpr int32_t FIXED_POINT_SCALE = 4096; // 12-bit fractional part
|
|
||||||
|
double lastFrameTime;
|
||||||
double lastFrameTime; // Last frame timestamp (in seconds, GLFW time)
|
double currentFrameTime;
|
||||||
double currentFrameTime; // Current frame timestamp
|
int32_t deltaTime;
|
||||||
int32_t deltaTime; // Delta time in fixed-point
|
float elapsedTime;
|
||||||
float elapsedTime; // Total elapsed time in seconds
|
|
||||||
|
|
||||||
// Convert float seconds to fixed-point
|
|
||||||
int32_t SecondsToFixed(float seconds) const;
|
int32_t SecondsToFixed(float seconds) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TIME_H
|
#endif
|
||||||
Reference in New Issue
Block a user