finish obj loader
This commit is contained in:
@@ -41,12 +41,16 @@ set(CMAKE_MODULE_PATH
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/CMake"
|
"${CMAKE_CURRENT_LIST_DIR}/CMake"
|
||||||
)
|
)
|
||||||
# Find required packages based on options
|
# Find required packages based on options
|
||||||
|
find_package(spdlog REQUIRED)
|
||||||
if (BASALT_CUDA_DELIVER)
|
if (BASALT_CUDA_DELIVER)
|
||||||
find_package(CUDA REQUIRED)
|
find_package(CUDA REQUIRED)
|
||||||
endif ()
|
endif ()
|
||||||
if (BASALT_DIRECTX11_ENGINE)
|
if (BASALT_DIRECTX11_ENGINE)
|
||||||
find_package(DirectX11 REQUIRED)
|
find_package(DirectX11 REQUIRED)
|
||||||
endif ()
|
endif ()
|
||||||
|
if (BASALT_OBJ_OBJECT_LOADER)
|
||||||
|
find_package(tinyobjloader REQUIRED)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
# Include projects
|
# Include projects
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ PRIVATE
|
|||||||
target_link_libraries(BasaltObjObjectLoader
|
target_link_libraries(BasaltObjObjectLoader
|
||||||
PRIVATE
|
PRIVATE
|
||||||
BasaltShared
|
BasaltShared
|
||||||
|
tinyobjloader
|
||||||
)
|
)
|
||||||
# Enable export macro
|
# Enable export macro
|
||||||
target_compile_definitions(BasaltObjObjectLoader
|
target_compile_definitions(BasaltObjObjectLoader
|
||||||
|
|||||||
@@ -1,9 +1,95 @@
|
|||||||
#include <basalt/export_macro.hpp>
|
#include <basalt/export_macro.hpp>
|
||||||
|
#include <basalt/object_loader.hpp>
|
||||||
|
#include <tiny_obj_loader.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace object_loader = ::basalt::shared::object_loader;
|
||||||
|
using object_loader::IObjectLoader;
|
||||||
|
using object_loader::Object;
|
||||||
|
using object_loader::ObjectLoaderConfig;
|
||||||
|
namespace math = ::basalt::shared::math;
|
||||||
|
using math::FloatPoint;
|
||||||
|
using math::Index;
|
||||||
|
using math::Triangle;
|
||||||
|
using math::Vector3;
|
||||||
|
|
||||||
|
class ObjObjectLoader : public IObjectLoader {
|
||||||
|
public:
|
||||||
|
ObjObjectLoader() {}
|
||||||
|
virtual ~ObjObjectLoader() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void load(ObjectLoaderConfig&& config) override {
|
||||||
|
IObjectLoader::load(std::move(config));
|
||||||
|
|
||||||
|
// Load the OBJ file using tinyobjloader
|
||||||
|
tinyobj::attrib_t attrib;
|
||||||
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
|
std::vector<tinyobj::material_t> materials;
|
||||||
|
std::string err;
|
||||||
|
|
||||||
|
// Load the OBJ file
|
||||||
|
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &err, this->config.filename.c_str())) {
|
||||||
|
throw std::runtime_error("fail to load obj file");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create one object from all shapes in the OBJ file
|
||||||
|
std::vector<Vector3> vertices;
|
||||||
|
std::vector<Triangle> triangles;
|
||||||
|
|
||||||
|
// Extract all vertices from the OBJ file
|
||||||
|
// In tinyobjloader, vertices are stored in a flat array [x,y,z,x,y,z,...]
|
||||||
|
size_t num_vertices = attrib.vertices.size() / 3;
|
||||||
|
vertices.reserve(num_vertices);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < attrib.vertices.size(); i += 3) {
|
||||||
|
Vector3 vertex;
|
||||||
|
vertex.x = attrib.vertices[i + 0]; // x coordinate
|
||||||
|
vertex.y = attrib.vertices[i + 1]; // y coordinate
|
||||||
|
vertex.z = attrib.vertices[i + 2]; // z coordinate
|
||||||
|
vertices.emplace_back(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each shape and add its triangles
|
||||||
|
for (const auto& shape : shapes) {
|
||||||
|
// Add triangles from this shape to our collection
|
||||||
|
// Each face in the shape has been triangulated by tinyobjloader
|
||||||
|
for (size_t i = 0; i < shape.mesh.indices.size(); i += 3) {
|
||||||
|
if (i + 2 < shape.mesh.indices.size()) {
|
||||||
|
Triangle triangle;
|
||||||
|
|
||||||
|
// Get the three indices that form the triangle
|
||||||
|
// vertex_index is the index into the attrib.vertices array
|
||||||
|
int idx0 = shape.mesh.indices[i + 0].vertex_index;
|
||||||
|
int idx1 = shape.mesh.indices[i + 1].vertex_index;
|
||||||
|
int idx2 = shape.mesh.indices[i + 2].vertex_index;
|
||||||
|
|
||||||
|
// Make sure indices are valid
|
||||||
|
if (idx0 >= 0 && idx1 >= 0 && idx2 >= 0) {
|
||||||
|
triangle.i = static_cast<Index>(idx0);
|
||||||
|
triangle.j = static_cast<Index>(idx1);
|
||||||
|
triangle.k = static_cast<Index>(idx2);
|
||||||
|
|
||||||
|
triangles.emplace_back(triangle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an Object and add it to our objects vector
|
||||||
|
if (vertices.empty() || triangles.empty()) {
|
||||||
|
throw std::runtime_error("empty scene is not allowed");
|
||||||
|
} else {
|
||||||
|
this->objects.emplace_back(std::move(vertices), std::move(triangles));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
BS_EXPORT void* BSCreateInstance() {
|
BS_EXPORT void* BSCreateInstance() {
|
||||||
return nullptr;
|
return static_cast<IObjectLoader*>(new ObjObjectLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
BS_EXPORT void BSDestroyInstance(void* instance) {
|
BS_EXPORT void BSDestroyInstance(void* instance) {
|
||||||
return;
|
delete dynamic_cast<ObjObjectLoader*>(static_cast<IObjectLoader*>(instance));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <basalt/char_types.hpp>
|
#include <basalt/char_types.hpp>
|
||||||
#include <basalt/engine.hpp>
|
#include <basalt/engine.hpp>
|
||||||
#include <basalt/deliver.hpp>
|
#include <basalt/deliver.hpp>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace engine = ::basalt::shared::engine;
|
namespace engine = ::basalt::shared::engine;
|
||||||
using engine::EngineConfig;
|
using engine::EngineConfig;
|
||||||
@@ -20,18 +21,22 @@ using ::basalt::presenter::cmd_client::CmdClient;
|
|||||||
using ::basalt::presenter::stopwatch::Stopwatch;
|
using ::basalt::presenter::stopwatch::Stopwatch;
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
spdlog::info("Finding plugins...");
|
||||||
auto engine_dll = DllLoader(DllKind::Engine, BSTEXT("BasaltDirectX11Engine"));
|
auto engine_dll = DllLoader(DllKind::Engine, BSTEXT("BasaltDirectX11Engine"));
|
||||||
auto deliver_dll = DllLoader(DllKind::Deliver, BSTEXT("BasaltPipeDeliver"));
|
auto deliver_dll = DllLoader(DllKind::Deliver, BSTEXT("BasaltPipeDeliver"));
|
||||||
|
|
||||||
auto client = CmdClient();
|
auto client = CmdClient();
|
||||||
|
spdlog::info("Waiting BasaltTrainer...");
|
||||||
auto payload = client.wait_handshake();
|
auto payload = client.wait_handshake();
|
||||||
|
|
||||||
|
spdlog::info("Allocating resources...");
|
||||||
auto* engine = engine_dll.create_instance<IEngine>();
|
auto* engine = engine_dll.create_instance<IEngine>();
|
||||||
//auto* deliver = deliver_dll.create_instance<IDeliver>();
|
//auto* deliver = deliver_dll.create_instance<IDeliver>();
|
||||||
|
|
||||||
EngineConfig engine_config{.headless = false, .width = payload.width, .height = payload.height};
|
EngineConfig engine_config{.headless = false, .width = payload.width, .height = payload.height};
|
||||||
engine->startup(std::move(engine_config));
|
engine->startup(std::move(engine_config));
|
||||||
|
|
||||||
|
spdlog::info("Start to running.");
|
||||||
Stopwatch stopwatch(120);
|
Stopwatch stopwatch(120);
|
||||||
while (true) {
|
while (true) {
|
||||||
auto req_stop = engine->tick();
|
auto req_stop = engine->tick();
|
||||||
@@ -40,6 +45,9 @@ int main(int argc, char* argv[]) {
|
|||||||
if (can_stop) break;
|
if (can_stop) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spdlog::info("Destroying resources...");
|
||||||
engine->shutdown();
|
engine->shutdown();
|
||||||
engine_dll.destroy_instance(engine);
|
engine_dll.destroy_instance(engine);
|
||||||
|
|
||||||
|
spdlog::info("Program stop.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "stopwatch.hpp"
|
#include "stopwatch.hpp"
|
||||||
#include <print>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace basalt::presenter::stopwatch {
|
namespace basalt::presenter::stopwatch {
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ namespace basalt::presenter::stopwatch {
|
|||||||
auto frame_time = static_cast<double>(time_diff.count()) / this->interval;
|
auto frame_time = static_cast<double>(time_diff.count()) / this->interval;
|
||||||
auto fps = 1000.0 / frame_time;
|
auto fps = 1000.0 / frame_time;
|
||||||
// 输出给用户
|
// 输出给用户
|
||||||
std::print("FPS: {:.2f} Frame Time: {:.4f} ms\n", fps, frame_time);
|
spdlog::info("FPS: {:.2f} Frame Time: {:.4f} ms", fps, frame_time);
|
||||||
|
|
||||||
// 把结束时间设置为开始时间继续下一轮循环
|
// 把结束时间设置为开始时间继续下一轮循环
|
||||||
this->start_point = stop_point;
|
this->start_point = stop_point;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ We assume that you executing following commands in the root directory of `Basalt
|
|||||||
|
|
||||||
### spdlog
|
### spdlog
|
||||||
|
|
||||||
|
##### Build
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd external
|
cd external
|
||||||
git clone -b 1.17.0 https://github.com/gabime/spdlog.git
|
git clone -b 1.17.0 https://github.com/gabime/spdlog.git
|
||||||
@@ -19,53 +21,65 @@ mkdir out
|
|||||||
cd out
|
cd out
|
||||||
mkdir build
|
mkdir build
|
||||||
mkdir install
|
mkdir install
|
||||||
|
cd build
|
||||||
```
|
```
|
||||||
|
|
||||||
In Windows:
|
In Windows:
|
||||||
|
|
||||||
```bat
|
```bat
|
||||||
cmake -A x64 ../..
|
cmake -A x64 -DCMAKE_CXX_STANDARD=23 -DSPDLOG_WCHAR_SUPPORT=ON -DSPDLOG_WCHAR_FILENAMES=ON -DSPDLOG_WCHAR_CONSOLE=ON -DSPDLOG_BUILD_EXAMPLE=OFF ../..
|
||||||
cmake --build . --config Release
|
cmake --build . --config Release
|
||||||
cmake --install . --prefix=../install
|
cmake --install . --config Release --prefix=../install
|
||||||
```
|
```
|
||||||
|
|
||||||
Or in POSIX:
|
Or in POSIX:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release ../..
|
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 -DSPDLOG_BUILD_EXAMPLE=OFF ../..
|
||||||
cmake --build .
|
cmake --build .
|
||||||
cmake --install . --prefix=../install
|
cmake --install . --prefix=../install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### Usage
|
||||||
|
|
||||||
|
Use `-Dspdlog_ROOT=<path to spdlog install directory>` in cmake when you configure this project.
|
||||||
|
|
||||||
#### tinyobjloader
|
#### tinyobjloader
|
||||||
|
|
||||||
|
##### Build
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd external
|
cd external
|
||||||
git clone -b v2.0.0 https://github.com/tinyobjloader/tinyobjloader.git
|
git clone -b v1.0.6 https://github.com/tinyobjloader/tinyobjloader.git
|
||||||
|
|
||||||
cd tinyobjloader
|
cd tinyobjloader
|
||||||
mkdir out
|
mkdir out
|
||||||
cd out
|
cd out
|
||||||
mkdir build
|
mkdir build
|
||||||
mkdir install
|
mkdir install
|
||||||
|
cd build
|
||||||
```
|
```
|
||||||
|
|
||||||
In Windows:
|
In Windows:
|
||||||
|
|
||||||
```bat
|
```bat
|
||||||
cmake -A x64 ../..
|
cmake -A x64 -DCMAKE_CXX_STANDARD=23 ../..
|
||||||
cmake --build . --config Release
|
cmake --build . --config Release
|
||||||
cmake --install . --prefix=../install
|
cmake --install . --config Release --prefix=../install
|
||||||
```
|
```
|
||||||
|
|
||||||
Or in POSIX:
|
Or in POSIX:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release ../..
|
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 ../..
|
||||||
cmake --build .
|
cmake --build .
|
||||||
cmake --install . --prefix=../install
|
cmake --install . --prefix=../install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### Usage
|
||||||
|
|
||||||
|
Use `-Dtinyobjloader_ROOT=<path to tinyobjloader install directory>` in cmake when you configure this project.
|
||||||
|
|
||||||
## Warning
|
## Warning
|
||||||
|
|
||||||
This project was not written robustly.
|
This project was not written robustly.
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ PUBLIC
|
|||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>"
|
||||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||||
)
|
)
|
||||||
|
target_link_libraries(BasaltShared
|
||||||
|
PUBLIC
|
||||||
|
spdlog::spdlog
|
||||||
|
)
|
||||||
target_compile_definitions(BasaltShared
|
target_compile_definitions(BasaltShared
|
||||||
PUBLIC
|
PUBLIC
|
||||||
$<$<PLATFORM_ID:Windows>:BASALT_OS_WINDOWS>
|
$<$<PLATFORM_ID:Windows>:BASALT_OS_WINDOWS>
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ namespace basalt::shared::object_loader {
|
|||||||
|
|
||||||
IObjectLoader::~IObjectLoader() {}
|
IObjectLoader::~IObjectLoader() {}
|
||||||
|
|
||||||
void IObjectLoader::load() {
|
void IObjectLoader::load(ObjectLoaderConfig&& config) {
|
||||||
if (this->status != ObjectLoaderStatus::Ready) throw std::runtime_error("unexpected object loader status");
|
if (this->status != ObjectLoaderStatus::Ready) throw std::runtime_error("unexpected object loader status");
|
||||||
|
this->config = std::move(config);
|
||||||
this->status = ObjectLoaderStatus::Loaded;
|
this->status = ObjectLoaderStatus::Loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace basalt::shared::object_loader {
|
namespace basalt::shared::object_loader {
|
||||||
|
|
||||||
@@ -20,6 +21,10 @@ namespace basalt::shared::object_loader {
|
|||||||
std::vector<math::Triangle> triangles;
|
std::vector<math::Triangle> triangles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ObjectLoaderConfig {
|
||||||
|
std::string filename;
|
||||||
|
};
|
||||||
|
|
||||||
enum class ObjectLoaderStatus {
|
enum class ObjectLoaderStatus {
|
||||||
Ready,
|
Ready,
|
||||||
Loaded,
|
Loaded,
|
||||||
@@ -37,12 +42,13 @@ namespace basalt::shared::object_loader {
|
|||||||
virtual ~IObjectLoader();
|
virtual ~IObjectLoader();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void load();
|
virtual void load(ObjectLoaderConfig&& config);
|
||||||
const Object& get_object(size_t index) const;
|
const Object& get_object(size_t index) const;
|
||||||
size_t get_object_count() const;
|
size_t get_object_count() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ObjectLoaderStatus status;
|
ObjectLoaderStatus status;
|
||||||
|
ObjectLoaderConfig config;
|
||||||
std::vector<Object> objects;
|
std::vector<Object> objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user