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 <ylt/struct_pack.hpp>
|
||||||
#include <iostream>
|
#include "template.h"
|
||||||
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;
|
|
||||||
struct person {
|
struct person {
|
||||||
int64_t id;
|
int64_t id;
|
||||||
std::string name;
|
std::string name;
|
||||||
int age;
|
int age;
|
||||||
double salary;
|
double salary;
|
||||||
};
|
};
|
||||||
template <typename T, typename construct_param_t, typename = void, typename... Args>
|
//STRUCT_PACK_REFL(person, ID, name, age);
|
||||||
struct is_constructable_impl : std::false_type {};
|
inline person& STRUCT_PACK_REFL_FLAG(person& t) {
|
||||||
|
return t;
|
||||||
template <typename T, typename construct_param_t, typename... Args>
|
}
|
||||||
struct is_constructable_impl < T, construct_param_t,
|
template<typename T> constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL();
|
||||||
std::void_t<
|
template<> constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL<person>() {
|
||||||
decltype(T{ {Args{}}..., {construct_param_t{}} }) > , Args... >
|
return 3;
|
||||||
: std::true_type {};
|
}
|
||||||
|
inline decltype(auto) STRUCT_PACK_FIELD_COUNT(const person&) {
|
||||||
template <typename T, typename construct_param_t, typename... Args>
|
return std::integral_constant<std::size_t, 3>{};
|
||||||
bool is_constructable = is_constructable_impl<T, construct_param_t, void, Args...>::value;
|
}
|
||||||
|
template<std::size_t I> auto& STRUCT_PACK_GET(person& c) {
|
||||||
template <typename T, typename... Args>
|
if constexpr (0 == I) {
|
||||||
std::size_t members_count_impl() {
|
return c.age;
|
||||||
if (is_constructable<T, UniversalVectorType, Args...>) {
|
} if constexpr (1 == I) {
|
||||||
cout << "is_constructable UniversalVectorType \n";
|
return c.name;
|
||||||
//return members_count_impl<T, Args..., UniversalVectorType>();
|
} if constexpr (2 == I) {
|
||||||
}
|
return c.ID;
|
||||||
else if (is_constructable<T, UniversalType, Args...>) {
|
|
||||||
cout << "is_constructable UniversalType \n";
|
|
||||||
//return members_count_impl<T, UniversalType, Args...>();
|
|
||||||
}
|
}
|
||||||
else {
|
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() {
|
int main() {
|
||||||
person person1{ .id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42 };
|
person person1{ .id = 1, .name = "hello struct pack", .age = 20, .salary = 1024.42 };
|
||||||
|
|
||||||
using type = remove_cvref_t<decltype(person1)>;
|
using type = remove_cvref_t<decltype(person1)>;
|
||||||
using type2 = remove_cvref_t<type>;
|
auto c1 = members_count<type>;
|
||||||
auto Count = members_count<type>;
|
int c2 = members_count_impl<type>();
|
||||||
int isc = members_count_impl<type2>();
|
int c3 = detail::members_count<type>();
|
||||||
int c2 = detail::members_count<type>();
|
|
||||||
// 1行代码序列化
|
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);
|
vector<char> buffer = serialize(person1);
|
||||||
|
|
||||||
// 只反序列化person的第2个字段
|
// 只反序列化person的第2个字段
|
||||||
auto name = get_field<person, 1>(buffer.data(), buffer.size());
|
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)
|
on_install(function (package)
|
||||||
os.cp("include", package:installdir())
|
os.cp("include", package:installdir())
|
||||||
end)
|
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")
|
set_kind("binary")
|
||||||
add_packages("ylt")
|
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