update vertex pack
This commit is contained in:
parent
378e0c12a7
commit
cadadd934f
59
engine/3rdparty/ylt/include/parray.h
vendored
Normal file
59
engine/3rdparty/ylt/include/parray.h
vendored
Normal 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++;
|
||||
};
|
||||
};
|
||||
0
engine/3rdparty/ylt/include/struct_member.h
vendored
Normal file
0
engine/3rdparty/ylt/include/struct_member.h
vendored
Normal file
80
engine/3rdparty/ylt/include/template.h
vendored
Normal file
80
engine/3rdparty/ylt/include/template.h
vendored
Normal 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
52
engine/3rdparty/ylt/include/vertex.h
vendored
Normal 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) {};
|
||||
};
|
||||
|
||||
|
||||
|
||||
105
engine/3rdparty/ylt/test/struct_pack.cpp
vendored
105
engine/3rdparty/ylt/test/struct_pack.cpp
vendored
@ -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;
|
||||
}
|
||||
35
engine/3rdparty/ylt/test/vertex_wrap.cpp
vendored
Normal file
35
engine/3rdparty/ylt/test/vertex_wrap.cpp
vendored
Normal 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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
12
engine/3rdparty/ylt/xmake.lua
vendored
12
engine/3rdparty/ylt/xmake.lua
vendored
@ -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")
|
||||
Loading…
Reference in New Issue
Block a user