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) {}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										107
									
								
								engine/3rdparty/ylt/test/struct_pack.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										107
									
								
								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