update vertex pack

This commit is contained in:
ouczbs 2024-03-30 17:55:00 +08:00
parent 378e0c12a7
commit cadadd934f
7 changed files with 303 additions and 42 deletions

59
engine/3rdparty/ylt/include/parray.h vendored Normal file
View File

@ -0,0 +1,59 @@
#pragma once
#include <concepts>
template<typename P>
requires requires {typename P::UClass;}
class parray {
using UClass = P::UClass;
protected:
uint32_t t_size;
uint32_t m_size;
uint32_t m_head{ 0 };
char* m_buf;
UClass* u_class;
public:
~parray() {
if (m_buf) {
free(m_buf);
}
}
parray(uint32_t tsize, uint32_t size, UClass* uclass)
: t_size(tsize), m_buf((char*)malloc(tsize* size)), m_size(size),u_class(uclass) {}
parray(parray& other) noexcept {
m_size = other.m_size;
m_head = other.m_head;
m_buf = other.m_buf;
other.m_buf = nullptr;
}
void* data() {
return m_buf;
}
uint32_t size() {
return m_head;
}
uint32_t data_size() {
return t_size * m_head;
};
P* at(int i){
if (i >= m_head) {
return nullptr;
}
return (P*)(m_buf + i * t_size);
};
};
template<typename P, typename T>
requires std::is_base_of<P, T>::value && requires {typename P::UClass; }
class ptarray : public parray<P>{
using parray<P>::m_head;
using parray<P>::m_size;
using parray<P>::m_buf;
using parray<P>::t_size;
public:
ptarray(uint32_t size = 1) : parray<P>(sizeof(T), size, new T::UClass()) {}
void push_back(T& t) {
if (m_head >= m_size) {
return;
}
*(T*)(m_buf + m_head * t_size) = t;
m_head++;
};
};

View File

80
engine/3rdparty/ylt/include/template.h vendored Normal file
View File

@ -0,0 +1,80 @@
#include <ylt/struct_pack.hpp>
#include <iostream>
using namespace std;
using namespace struct_pack;
using UniversalVectorType = detail::UniversalVectorType;
using UniversalType = detail::UniversalType;
using UniversalOptionalType = detail::UniversalOptionalType;
using UniversalIntegralType = detail::UniversalIntegralType;
using UniversalNullptrType = detail::UniversalNullptrType;
using UniversalCompatibleType = detail::UniversalCompatibleType;
/*
*/
template <typename T, typename construct_param_t, typename = void, typename... Args>
struct is_constructable_impl : std::false_type {};
template <typename T, typename construct_param_t, typename... Args>
struct is_constructable_impl < T, construct_param_t,
std::void_t<
decltype(T{ {Args{}}..., {construct_param_t{}} }) > , Args... >
: std::true_type {};
template <typename T, typename construct_param_t, typename... Args>
constexpr bool is_constructable = is_constructable_impl<T, construct_param_t, void, Args...>::value;
template <typename T, typename... Args>
constexpr std::size_t members_count_impl() {
if constexpr (is_constructable<T, UniversalVectorType, Args...>) {
return members_count_impl<T, Args..., UniversalVectorType>();
}
else if constexpr (is_constructable<T, UniversalType, Args...>) {
cout << "is_constructable UniversalType \n";
return members_count_impl<T, Args..., UniversalType>();
}
return sizeof...(Args);
}
/*
*/
template <typename Type>
concept type_string = requires(Type container) {
requires detail::is_char_t<typename std::remove_cvref_t<Type>::value_type>;
container.length();
container.data();
};
template <typename Type>
concept type_struct = requires(Type container) {
requires std::is_class_v<Type>;
};
template <typename Type>
concept type_u32 = requires(Type container) {
requires sizeof(Type) == 4;
};
/*
*/
template <typename T>
constexpr void visit_one_member_info(T& item) {
constexpr auto id = detail::get_type_id<T, 0>();
cout << "visit_one_member_info::" << (int)id << "=" << item << "\n";
}
template <typename... Args>
void visit_member_info(Args&...args) {
cout << "visit_member_info::" << sizeof...(args) << "\n";
(visit_one_member_info(args), ...);
}
template <typename T>
void visit_struct_info(T& item) {
int count = members_count_impl<T>();
auto visitor = [](auto&&... items) {
visit_member_info<>(items...);
};
if (count == 4) {
auto&& [a1, a2, a3, a4] = item;
visitor(a1, a2, a3, a4);
}
}

52
engine/3rdparty/ylt/include/vertex.h vendored Normal file
View File

@ -0,0 +1,52 @@
#pragma once
#include <cstdint>
#include <tuple>
#include <vector>
using namespace std;
#define sizeof_field(_struct, _field) sizeof(((_struct*)0)->_field)
// 顶点最多关联4个骨骼
#define MAX_NUM_BONES_PER_VERTEX 4
struct Vector2 {
float x;
float y;
};
struct Vector3 {
float x;
float y;
float z;
};
struct Vertex {
struct UClass {
virtual void BindLayout() = 0;
};
};
struct PosVertex : public Vertex {
Vector3 Position = {};
struct UClass : public Vertex::UClass{
int MemCount = 1;
tuple<int, int> Position{sizeof_field(PosVertex, Position), offsetof(PosVertex, Position)};
virtual void BindLayout() {};
};
};
struct TexVertex : public Vertex {
Vector3 Position = {};
Vector3 Normal = {};
Vector2 TexCoords = {};
};
struct BoneVertex : public Vertex
{
Vector3 Position = {};
Vector2 TexCoords = {};
Vector3 Normal = {};
Vector3 Tangent = {};
// 骨骼蒙皮数据
float Weights[MAX_NUM_BONES_PER_VERTEX] = {};
uint32_t BoneIDs[MAX_NUM_BONES_PER_VERTEX] = {};
void AddBoneData(uint32_t boneID, float weight) {};
};

View File

@ -1,58 +1,85 @@
#include <ylt/struct_pack.hpp>
#include <iostream>
using namespace std;
using namespace struct_pack;
using UniversalVectorType = detail::UniversalVectorType;
using UniversalType = detail::UniversalType;
using UniversalOptionalType = detail::UniversalOptionalType;
using UniversalIntegralType = detail::UniversalIntegralType;
using UniversalNullptrType = detail::UniversalNullptrType;
using UniversalCompatibleType = detail::UniversalCompatibleType;
#include "template.h"
struct person {
int64_t id;
std::string name;
int age;
double salary;
};
template <typename T, typename construct_param_t, typename = void, typename... Args>
struct is_constructable_impl : std::false_type {};
template <typename T, typename construct_param_t, typename... Args>
struct is_constructable_impl < T, construct_param_t,
std::void_t<
decltype(T{ {Args{}}..., {construct_param_t{}} }) > , Args... >
: std::true_type {};
template <typename T, typename construct_param_t, typename... Args>
bool is_constructable = is_constructable_impl<T, construct_param_t, void, Args...>::value;
template <typename T, typename... Args>
std::size_t members_count_impl() {
if (is_constructable<T, UniversalVectorType, Args...>) {
cout << "is_constructable UniversalVectorType \n";
//return members_count_impl<T, Args..., UniversalVectorType>();
}
else if (is_constructable<T, UniversalType, Args...>) {
cout << "is_constructable UniversalType \n";
//return members_count_impl<T, UniversalType, Args...>();
//STRUCT_PACK_REFL(person, ID, name, age);
inline person& STRUCT_PACK_REFL_FLAG(person& t) {
return t;
}
template<typename T> constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL();
template<> constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL<person>() {
return 3;
}
inline decltype(auto) STRUCT_PACK_FIELD_COUNT(const person&) {
return std::integral_constant<std::size_t, 3>{};
}
template<std::size_t I> auto& STRUCT_PACK_GET(person& c) {
if constexpr (0 == I) {
return c.age;
} if constexpr (1 == I) {
return c.name;
} if constexpr (2 == I) {
return c.ID;
}
else {
return sizeof...(Args);
static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL<person>());
}
return sizeof...(Args);
}
}
template<std::size_t I> const auto& STRUCT_PACK_GET(const person& c) {
if constexpr (0 == I) {
return c.age;
} if constexpr (1 == I) {
return c.name;
} if constexpr (2 == I) {
return c.ID;
}
else {
static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL<person>());
}
}
inline auto& STRUCT_PACK_GET_0(person& c) {
return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 0>(c);
}
inline auto& STRUCT_PACK_GET_1(person& c) {
return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 1>(c);
}
inline auto& STRUCT_PACK_GET_2(person& c) {
return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 2>(c);
}
inline const auto& STRUCT_PACK_GET_0(const person& c) {
return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 0>(c);
}
inline const auto& STRUCT_PACK_GET_1(const person& c) {
return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 1>(c);
}
inline const auto& STRUCT_PACK_GET_2(const person& c) {
return STRUCT_PACK_GET<STRUCT_PACK_FIELD_COUNT_IMPL<person>() - 1 - 2>(c);
};
int main() {
person person1{ .id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42 };
using type = remove_cvref_t<decltype(person1)>;
using type2 = remove_cvref_t<type>;
auto Count = members_count<type>;
int isc = members_count_impl<type2>();
int c2 = detail::members_count<type>();
// 1行代码序列化
auto c1 = members_count<type>;
int c2 = members_count_impl<type>();
int c3 = detail::members_count<type>();
auto id = detail::get_type_id<type>();
auto t1 = type_struct<type>;
auto t2 = type_string<decltype(person1.name)>;
auto t3 = type_u32<decltype(person1.age)>;
visit_struct_info<decltype(person1)>(person1);
visit_member_info<>(person1.name, person1.age);
auto sz_info = detail::calculate_payload_size(person1);
// 1行代码序列化
vector<char> buffer = serialize(person1);
// 只反序列化person的第2个字段
// 只反序列化person的第2个字段
auto name = get_field<person, 1>(buffer.data(), buffer.size());
cout << "hello " << name.value() << "Count == " << Count << c2;
cout << "hello " << name.value() << "Count == " << c1;
}

View File

@ -0,0 +1,35 @@
#include <cstdint>
#include <tuple>
#include <iostream>
#include "vertex.h"
#include "parray.h"
//方案一,使用静态变量存储数据
//方案二,模板元编程,传递数据
int main() {
cout << "std::is_aggregate_v<PosVertex> = "<< is_aggregate_v<PosVertex> << endl;
cout << "std::is_aggregate_v<TexVertex> = "<< is_aggregate_v<TexVertex> << endl;
cout << "std::is_aggregate_v<BoneVertex> = "<< is_aggregate_v<BoneVertex> << endl;
float x1 = 1.0, x2 = 2.0, x3 = 3.0;
PosVertex p;
TexVertex t;
BoneVertex b;
ptarray<Vertex, PosVertex> vertices(10);
//ptarray<Vertex, TexVertex> vertices2(10);
vertices.push_back(p);
parray<Vertex> pv = vertices;
auto Position = make_tuple(1, 2, 3);
auto pv0 = *(PosVertex*)pv.at(0);
//vertices.push_back(t);
cout<< "sizeof " << sizeof(p) << "," << sizeof(t) << "," << sizeof(b)<<"\n";
//auto r1 = b.BindLayout();
//auto r2 = t.BindLayout();
//auto r3 = p.BindLayout();
//cout << "vector " << get<0>(r1[0]) << "," << get<0>(r2[0]) << "," << get<0>(r3[0]) << "\n";
}

View File

@ -5,8 +5,16 @@ package("ylt")
on_install(function (package)
os.cp("include", package:installdir())
end)
-- target("ylt_struct_pack")
-- set_kind("binary")
-- add_packages("ylt")
-- add_includedirs("include")
-- add_headerfiles("include/*.h")
-- add_files("test/struct_pack.cpp")
target("ylt_struct_pack")
target("ylt_vertex_wrap")
set_kind("binary")
add_packages("ylt")
add_files("test/struct_pack.cpp")
add_includedirs("include")
add_headerfiles("include/*.h")
add_files("test/vertex_wrap.cpp")