write shit
This commit is contained in:
@@ -26,7 +26,7 @@ option(BASALT_OBJ_OBJECT_LOADER "Build with Wavefront OBJ 3D object loader suppo
|
|||||||
option(BASALT_GLTF_OBJECT_LOADER "Build with glTF 3D object loader support." OFF)
|
option(BASALT_GLTF_OBJECT_LOADER "Build with glTF 3D object loader support." OFF)
|
||||||
option(BASALT_ASSIMP_OBJECT_LOADER "Build with Assimp 3D object loader support." OFF)
|
option(BASALT_ASSIMP_OBJECT_LOADER "Build with Assimp 3D object loader support." OFF)
|
||||||
# Camera Motion Loaders
|
# Camera Motion Loaders
|
||||||
option(BASALT_homemade_ANIME_LOADER "Build with homemade camera motion loader support." OFF)
|
option(BASALT_CHICKENNUGGET_ANIME_LOADER "Build with chicken nugget camera motion loader support." OFF)
|
||||||
|
|
||||||
# Set C++ standards
|
# Set C++ standards
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
if (BASALT_CHICKENNUGGET_ANIME_LOADER)
|
||||||
|
add_subdirectory(ChickenNuggetAnimeLoader)
|
||||||
|
endif ()
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Create shared library
|
||||||
|
add_library(BasaltChickenNuggetAnimeLoader SHARED "")
|
||||||
|
# Setup sources
|
||||||
|
target_sources(BasaltChickenNuggetAnimeLoader
|
||||||
|
PRIVATE
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
# Setup header infomation
|
||||||
|
target_include_directories(BasaltChickenNuggetAnimeLoader
|
||||||
|
PRIVATE
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}"
|
||||||
|
)
|
||||||
|
# Setup linked library infomation
|
||||||
|
target_link_libraries(BasaltChickenNuggetAnimeLoader
|
||||||
|
PRIVATE
|
||||||
|
BasaltShared
|
||||||
|
)
|
||||||
|
# Enable export macro
|
||||||
|
target_compile_definitions(BasaltChickenNuggetAnimeLoader
|
||||||
|
PRIVATE
|
||||||
|
BS_EXPORTING
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install BasaltChickenNuggetAnimeLoader only on Release mode
|
||||||
|
install(TARGETS BasaltChickenNuggetAnimeLoader
|
||||||
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}/plugin/anime_loader"
|
||||||
|
)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#include <basalt/export_macro.hpp>
|
||||||
|
#include <basalt/anime_loader.hpp>
|
||||||
|
#include <basalt/math.hpp>
|
||||||
|
|
||||||
|
namespace anime_loader = ::basalt::shared::anime_loader;
|
||||||
|
using anime_loader::IAnimeLoader;
|
||||||
|
using anime_loader::KeyFrame;
|
||||||
|
|
||||||
|
using ::basalt::shared::math::FloatPoint;
|
||||||
|
#define F(x) (static_cast<FloatPoint>(x))
|
||||||
|
|
||||||
|
class ChickenNuggetAnimeLoader : public IAnimeLoader {
|
||||||
|
public:
|
||||||
|
ChickenNuggetAnimeLoader() {}
|
||||||
|
virtual ~ChickenNuggetAnimeLoader() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void internal_load() override {
|
||||||
|
this->frames.emplace(60 * 0, KeyFrame{.position = {F(0), F(-10), F(10)}, .rotation = {F(0.382683), F(0), F(0), F(0.92388)}});
|
||||||
|
this->frames.emplace(60 * 1,
|
||||||
|
KeyFrame{.position = {F(-10), F(0), F(10)},
|
||||||
|
.rotation = {F(0.270598), F(-0.270598), F(-0.653282), F(0.653282)}});
|
||||||
|
this->frames.emplace(60 * 2, KeyFrame{.position = {F(0), F(10), F(10)}, .rotation = {F(0), F(-0.382683), F(-0.92388), F(0)}});
|
||||||
|
this->frames.emplace(60 * 3,
|
||||||
|
KeyFrame{.position = {F(10), F(0), F(10)},
|
||||||
|
.rotation = {F(-0.270598), F(-0.270598), F(-0.653282), F(-0.653282)}});
|
||||||
|
this->frames.emplace(60 * 4,
|
||||||
|
KeyFrame{.position = {F(0), F(-10), F(10)},
|
||||||
|
.rotation = {F(0.382683), F(0), F(0), F(0.92388)}}); // Same as the first
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BS_EXPORT void* BSCreateInstance() {
|
||||||
|
return static_cast<IAnimeLoader*>(new ChickenNuggetAnimeLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
BS_EXPORT void BSDestroyInstance(void* instance) {
|
||||||
|
delete dynamic_cast<ChickenNuggetAnimeLoader*>(static_cast<IAnimeLoader*>(instance));
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
if (BASALT_OBJ_OBJECT_LOADER)
|
||||||
|
add_subdirectory(ObjObjectLoader)
|
||||||
|
endif ()
|
||||||
|
# if (BASALT_GLTF_OBJECT_LOADER)
|
||||||
|
# add_subdirectory(GltfObjectLoader)
|
||||||
|
# endif ()
|
||||||
|
# if (BASALT_ASSIMP_OBJECT_LOADER)
|
||||||
|
# add_subdirectory(AssimpObjectLoader)
|
||||||
|
# endif ()
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Create shared library
|
||||||
|
add_library(BasaltObjObjectLoader SHARED "")
|
||||||
|
# Setup sources
|
||||||
|
target_sources(BasaltObjObjectLoader
|
||||||
|
PRIVATE
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
# Setup header infomation
|
||||||
|
target_include_directories(BasaltObjObjectLoader
|
||||||
|
PRIVATE
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}"
|
||||||
|
)
|
||||||
|
# Setup linked library infomation
|
||||||
|
target_link_libraries(BasaltObjObjectLoader
|
||||||
|
PRIVATE
|
||||||
|
BasaltShared
|
||||||
|
)
|
||||||
|
# Enable export macro
|
||||||
|
target_compile_definitions(BasaltObjObjectLoader
|
||||||
|
PRIVATE
|
||||||
|
BS_EXPORTING
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install BasaltObjObjectLoader only on Release mode
|
||||||
|
install(TARGETS BasaltObjObjectLoader
|
||||||
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}/plugin/object_loader"
|
||||||
|
)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include <basalt/export_macro.hpp>
|
||||||
|
|
||||||
|
BS_EXPORT void* BSCreateInstance() {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
BS_EXPORT void BSDestroyInstance(void* instance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -1,13 +1,70 @@
|
|||||||
#include "anime_loader.hpp"
|
#include "anime_loader.hpp"
|
||||||
|
|
||||||
|
using ::basalt::shared::math::FloatPoint;
|
||||||
|
|
||||||
namespace basalt::shared::anime_loader {
|
namespace basalt::shared::anime_loader {
|
||||||
|
|
||||||
IAnimeLoader::IAnimeLoader() {
|
#pragma region Anime Loader
|
||||||
|
|
||||||
|
IAnimeLoader::IAnimeLoader() : status(AnimeLoaderStatus::Ready), time(0), last_index(0) {}
|
||||||
|
|
||||||
|
IAnimeLoader::~IAnimeLoader() {}
|
||||||
|
|
||||||
|
void IAnimeLoader::load() {
|
||||||
|
if (this->status != AnimeLoaderStatus::Ready) throw std::runtime_error("unexpected anime loader status");
|
||||||
|
|
||||||
|
// load by user
|
||||||
|
internal_load();
|
||||||
|
|
||||||
|
// check empty
|
||||||
|
if (this->frames.empty()) throw std::runtime_error("no anime key frames.");
|
||||||
|
// Get last frame index
|
||||||
|
auto last_pair = this->frames.end();
|
||||||
|
--last_pair;
|
||||||
|
this->last_index = last_pair->first;
|
||||||
|
|
||||||
|
// change status
|
||||||
|
this->status = AnimeLoaderStatus::Loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
IAnimeLoader::~IAnimeLoader() {
|
KeyFrameSpan IAnimeLoader::tick() {
|
||||||
|
if (this->status != AnimeLoaderStatus::Loaded) throw std::runtime_error("unexpected anime loader status");
|
||||||
|
|
||||||
|
// Accumulate time
|
||||||
|
++this->time;
|
||||||
|
if (this->time > this->last_index) {
|
||||||
|
this->time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// 首先用lower_bound获取到不小于自身的项目(肯定能获取到)
|
||||||
|
auto lower_bound = this->frames.lower_bound(this->time);
|
||||||
|
// 获取下一帧,如果没有下一帧,就转换为自身
|
||||||
|
auto upper_bound = lower_bound;
|
||||||
|
++upper_bound;
|
||||||
|
if (upper_bound == this->frames.end()) {
|
||||||
|
upper_bound = lower_bound;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算归一化时间
|
||||||
|
FloatPoint next_time = static_cast<FloatPoint>(this->time - lower_bound->first)
|
||||||
|
/ static_cast<FloatPoint>(upper_bound->first - lower_bound->first + 1);
|
||||||
|
FloatPoint prev_time = static_cast<FloatPoint>(1) - next_time;
|
||||||
|
|
||||||
|
// 返回结构
|
||||||
|
return KeyFrameSpan{
|
||||||
|
.prev_time = prev_time,
|
||||||
|
.next_time = next_time,
|
||||||
|
.prev_position = lower_bound->second.position,
|
||||||
|
.next_position = upper_bound->second.position,
|
||||||
|
.prev_rotation = lower_bound->second.rotation,
|
||||||
|
.next_rotation = upper_bound->second.rotation,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void IAnimeLoader::internal_load() {
|
||||||
|
throw std::logic_error("unimplemented function");
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
} // namespace basalt::shared::anime_loader
|
||||||
|
|||||||
@@ -1,13 +1,60 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "math.hpp"
|
||||||
|
#include <map>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace basalt::shared::anime_loader {
|
namespace basalt::shared::anime_loader {
|
||||||
|
|
||||||
|
//struct KeyFrame {
|
||||||
|
// math::Index frame_index;
|
||||||
|
// math::Matrix4x4 transform;
|
||||||
|
//};
|
||||||
|
|
||||||
|
//struct KeyFrameCompare {
|
||||||
|
// bool operator()(const KeyFrame& lhs, const KeyFrame& rhs) const { return lhs.time < rhs.time; }
|
||||||
|
//};
|
||||||
|
|
||||||
|
struct KeyFrame {
|
||||||
|
math::Vector3 position;
|
||||||
|
math::Quaternion rotation;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyFrameSpan {
|
||||||
|
math::FloatPoint prev_time; ///< 归一化的到前一帧的时间,即两者加起来为1。
|
||||||
|
math::FloatPoint next_time; ///< 归一化的到后一帧的时间,即两者加起来为1。
|
||||||
|
math::Vector3 prev_position; ///< 前一帧的摄像机坐标。
|
||||||
|
math::Vector3 next_position; ///< 后一帧的摄像机坐标。
|
||||||
|
math::Quaternion prev_rotation; ///< 前一帧的摄像机旋转。
|
||||||
|
math::Quaternion next_rotation; ///< 后一帧的摄像机旋转。
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AnimeLoaderStatus {
|
||||||
|
Ready,
|
||||||
|
Loaded,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* \li 摄像机的transform基于Blender坐标系。
|
||||||
|
* \li 摄像机的默认状态与Blender摄像机一致,即初始指向-Z,+Y Up。
|
||||||
|
*/
|
||||||
class IAnimeLoader {
|
class IAnimeLoader {
|
||||||
public:
|
public:
|
||||||
IAnimeLoader();
|
IAnimeLoader();
|
||||||
virtual ~IAnimeLoader();
|
virtual ~IAnimeLoader();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void load();
|
||||||
|
KeyFrameSpan tick();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void internal_load();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AnimeLoaderStatus status;
|
||||||
|
math::Index time, last_index;
|
||||||
|
std::map<math::Index, KeyFrame> frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace basalt::shared::anime_loader
|
} // namespace basalt::shared::anime_loader
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace basalt::shared::deliver {
|
namespace basalt::shared::deliver {
|
||||||
|
|
||||||
IDeliver::IDeliver() {}
|
IDeliver::IDeliver() : status(DeliverStatus::Ready) {}
|
||||||
|
|
||||||
IDeliver::~IDeliver() {
|
IDeliver::~IDeliver() {
|
||||||
if (this->status != DeliverStatus::Stop) {
|
if (this->status != DeliverStatus::Stop) {
|
||||||
|
|||||||
@@ -1,7 +1,37 @@
|
|||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
#include <stdexcept> // Include for std::out_of_range
|
#include <stdexcept> // Include for std::out_of_range
|
||||||
|
|
||||||
namespace Basalt::Shared::Math {
|
namespace basalt::shared::math {
|
||||||
|
|
||||||
|
#pragma region Triangle
|
||||||
|
|
||||||
|
Index& Triangle::operator[](size_t index) {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return i;
|
||||||
|
case 1:
|
||||||
|
return j;
|
||||||
|
case 2:
|
||||||
|
return k;
|
||||||
|
default:
|
||||||
|
throw std::out_of_range("Triangle index out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Index& Triangle::operator[](size_t index) const {
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return i;
|
||||||
|
case 1:
|
||||||
|
return j;
|
||||||
|
case 2:
|
||||||
|
return k;
|
||||||
|
default:
|
||||||
|
throw std::out_of_range("Triangle index out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region Vector3
|
#pragma region Vector3
|
||||||
|
|
||||||
@@ -33,9 +63,9 @@ namespace Basalt::Shared::Math {
|
|||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region Vector4
|
#pragma region Quaternion
|
||||||
|
|
||||||
FloatPoint& Vector4::operator[](size_t index) {
|
FloatPoint& Quaternion::operator[](size_t index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
return x;
|
return x;
|
||||||
@@ -46,11 +76,11 @@ namespace Basalt::Shared::Math {
|
|||||||
case 3:
|
case 3:
|
||||||
return w;
|
return w;
|
||||||
default:
|
default:
|
||||||
throw std::out_of_range("Vector4 index out of range");
|
throw std::out_of_range("Quaternion index out of range");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const FloatPoint& Vector4::operator[](size_t index) const {
|
const FloatPoint& Quaternion::operator[](size_t index) const {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
return x;
|
return x;
|
||||||
@@ -61,22 +91,56 @@ namespace Basalt::Shared::Math {
|
|||||||
case 3:
|
case 3:
|
||||||
return w;
|
return w;
|
||||||
default:
|
default:
|
||||||
throw std::out_of_range("Vector4 index out of range");
|
throw std::out_of_range("Quaternion index out of range");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
//
|
||||||
|
//#pragma region Vector4
|
||||||
|
//
|
||||||
|
// FloatPoint& Vector4::operator[](size_t index) {
|
||||||
|
// switch (index) {
|
||||||
|
// case 0:
|
||||||
|
// return x;
|
||||||
|
// case 1:
|
||||||
|
// return y;
|
||||||
|
// case 2:
|
||||||
|
// return z;
|
||||||
|
// case 3:
|
||||||
|
// return w;
|
||||||
|
// default:
|
||||||
|
// throw std::out_of_range("Vector4 index out of range");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const FloatPoint& Vector4::operator[](size_t index) const {
|
||||||
|
// switch (index) {
|
||||||
|
// case 0:
|
||||||
|
// return x;
|
||||||
|
// case 1:
|
||||||
|
// return y;
|
||||||
|
// case 2:
|
||||||
|
// return z;
|
||||||
|
// case 3:
|
||||||
|
// return w;
|
||||||
|
// default:
|
||||||
|
// throw std::out_of_range("Vector4 index out of range");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//#pragma endregion
|
||||||
|
//
|
||||||
|
//#pragma region Matrix4x4
|
||||||
|
//
|
||||||
|
// Vector4& Matrix4x4::operator[](size_t index) {
|
||||||
|
// return data.at(index);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const Vector4& Matrix4x4::operator[](size_t index) const {
|
||||||
|
// return data.at(index);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//#pragma endregion
|
||||||
|
|
||||||
#pragma region Matrix4x4
|
} // namespace basalt::shared::math
|
||||||
|
|
||||||
Vector4& Matrix4x4::operator[](size_t index) {
|
|
||||||
return data.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vector4& Matrix4x4::operator[](size_t index) const {
|
|
||||||
return data.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
} // namespace Basalt::Shared::Math
|
|
||||||
@@ -1,10 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <cinttypes>
|
||||||
#include <array> // Include array for std::array::at
|
#include <array> // Include array for std::array::at
|
||||||
|
|
||||||
namespace Basalt::Shared::Math {
|
namespace basalt::shared::math {
|
||||||
|
|
||||||
using FloatPoint = float;
|
using FloatPoint = float;
|
||||||
|
using Index = std::uint32_t;
|
||||||
|
|
||||||
|
struct Triangle {
|
||||||
|
Index i, j, k;
|
||||||
|
|
||||||
|
Index& operator[](size_t index);
|
||||||
|
const Index& operator[](size_t index) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct Vector3 {
|
struct Vector3 {
|
||||||
FloatPoint x, y, z;
|
FloatPoint x, y, z;
|
||||||
@@ -13,30 +22,37 @@ namespace Basalt::Shared::Math {
|
|||||||
const FloatPoint& operator[](size_t index) const;
|
const FloatPoint& operator[](size_t index) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector4 {
|
struct Quaternion {
|
||||||
FloatPoint x, y, z, w;
|
FloatPoint x, y, z, w;
|
||||||
|
|
||||||
FloatPoint& operator[](size_t index);
|
FloatPoint& operator[](size_t index);
|
||||||
const FloatPoint& operator[](size_t index) const;
|
const FloatPoint& operator[](size_t index) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Matrix4x4 {
|
//struct Vector4 {
|
||||||
private:
|
// FloatPoint x, y, z, w;
|
||||||
std::array<Vector4, 4> data; // Use std::array instead of raw array for .at() method
|
|
||||||
|
|
||||||
public:
|
// FloatPoint& operator[](size_t index);
|
||||||
Vector4& operator[](size_t index);
|
// const FloatPoint& operator[](size_t index) const;
|
||||||
const Vector4& operator[](size_t index) const;
|
//};
|
||||||
};
|
|
||||||
|
|
||||||
#define NOT_IMPLEMENTED throw std::logic_error("not implemented function");
|
//struct Matrix4x4 {
|
||||||
|
//private:
|
||||||
|
// std::array<Vector4, 4> data; // Use std::array instead of raw array for .at() method
|
||||||
|
|
||||||
template<typename TNum, typename TVec>
|
//public:
|
||||||
struct Vector3Traits {};
|
// Vector4& operator[](size_t index);
|
||||||
|
// const Vector4& operator[](size_t index) const;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#define NOT_IMPLEMENTED throw std::logic_error("not implemented function");
|
||||||
|
//
|
||||||
|
// template<typename TNum, typename TVec>
|
||||||
|
// struct Vector3Traits {};
|
||||||
|
//
|
||||||
|
// template<typename TNum, typename TMat>
|
||||||
|
// struct Matrix4x4Traits {};
|
||||||
|
//
|
||||||
|
//#undef NOT_IMPLEMENTED
|
||||||
|
|
||||||
template<typename TNum, typename TMat>
|
} // namespace basalt::shared::math
|
||||||
struct Matrix4x4Traits {};
|
|
||||||
|
|
||||||
#undef NOT_IMPLEMENTED
|
|
||||||
|
|
||||||
} // namespace Basalt::Shared::Math
|
|
||||||
@@ -1,13 +1,57 @@
|
|||||||
#include "object_loader.hpp"
|
#include "object_loader.hpp"
|
||||||
|
#include "anime_loader.hpp"
|
||||||
|
|
||||||
|
using ::basalt::shared::math::Triangle;
|
||||||
|
using ::basalt::shared::math::Vector3;
|
||||||
|
|
||||||
namespace basalt::shared::object_loader {
|
namespace basalt::shared::object_loader {
|
||||||
|
|
||||||
IObjectLoader::IObjectLoader() {
|
#pragma region Object
|
||||||
|
|
||||||
|
Object::Object(std::vector<Vector3>&& vertices, std::vector<Triangle>&& triangles) :
|
||||||
|
vertices(std::move(vertices)), triangles(std::move(triangles)) {}
|
||||||
|
|
||||||
|
Object::~Object() {}
|
||||||
|
|
||||||
|
size_t Object::get_vertices_count() const {
|
||||||
|
return this->vertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
IObjectLoader::~IObjectLoader() {
|
const math::Vector3* Object::get_vertices() const {
|
||||||
|
return this->vertices.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
size_t Object::get_triangle_count() const {
|
||||||
|
return this->triangles.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const math::Triangle* Object::get_triangles() const {
|
||||||
|
return this->triangles.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Object Loader
|
||||||
|
|
||||||
|
IObjectLoader::IObjectLoader() : status(ObjectLoaderStatus::Ready) {}
|
||||||
|
|
||||||
|
IObjectLoader::~IObjectLoader() {}
|
||||||
|
|
||||||
|
void IObjectLoader::load() {
|
||||||
|
if (this->status != ObjectLoaderStatus::Ready) throw std::runtime_error("unexpected object loader status");
|
||||||
|
this->status = ObjectLoaderStatus::Loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Object& IObjectLoader::get_object(size_t index) const {
|
||||||
|
if (this->status != ObjectLoaderStatus::Loaded) throw std::runtime_error("unexpected object loader status");
|
||||||
|
return this->objects.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IObjectLoader::get_object_count() const {
|
||||||
|
if (this->status != ObjectLoaderStatus::Loaded) throw std::runtime_error("unexpected object loader status");
|
||||||
|
return this->objects.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
} // namespace basalt::shared::object_loader
|
||||||
|
|||||||
@@ -1,13 +1,49 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "math.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace basalt::shared::object_loader {
|
namespace basalt::shared::object_loader {
|
||||||
|
|
||||||
|
class Object {
|
||||||
|
public:
|
||||||
|
Object(std::vector<math::Vector3>&& vertices, std::vector<math::Triangle>&& triangles);
|
||||||
|
~Object();
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t get_vertices_count() const;
|
||||||
|
const math::Vector3* get_vertices() const;
|
||||||
|
size_t get_triangle_count() const;
|
||||||
|
const math::Triangle* get_triangles() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<math::Vector3> vertices;
|
||||||
|
std::vector<math::Triangle> triangles;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ObjectLoaderStatus {
|
||||||
|
Ready,
|
||||||
|
Loaded,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @details
|
||||||
|
* \li 加载的模型的坐标系与Blender一致。
|
||||||
|
* \li 加载的模型的顶点顺序为CCW,即右手定则确认法线方向。
|
||||||
|
*/
|
||||||
class IObjectLoader {
|
class IObjectLoader {
|
||||||
public:
|
public:
|
||||||
IObjectLoader();
|
IObjectLoader();
|
||||||
virtual ~IObjectLoader();
|
virtual ~IObjectLoader();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void load();
|
||||||
|
const Object& get_object(size_t index) const;
|
||||||
|
size_t get_object_count() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
ObjectLoaderStatus status;
|
||||||
|
std::vector<Object> objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace basalt::shared::object_loader
|
} // namespace basalt::shared::object_loader
|
||||||
|
|||||||
Reference in New Issue
Block a user