-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathMeshLoader.cpp
117 lines (101 loc) · 3.05 KB
/
MeshLoader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "stdafx.h"
#include "AssetLoaders.h"
namespace happy
{
template <typename T> T read(istream &s)
{
T val;
s.read(reinterpret_cast<char*>(&val), sizeof(T));
return val;
}
template<> VertexPositionNormalTangentBinormalTexcoordIndicesWeights read(istream &s)
{
VertexPositionNormalTangentBinormalTexcoordIndicesWeights vertex;
vertex.pos = read<bb::vec4>(s);
vertex.normal = read<bb::vec3>(s);
vertex.tangent = read<bb::vec3>(s);
vertex.binormal = read<bb::vec3>(s);
vertex.texcoord = read<bb::vec2>(s);
vertex.indices[0] = read<Index16>(s);
vertex.indices[1] = read<Index16>(s);
vertex.indices[2] = read<Index16>(s);
vertex.indices[3] = read<Index16>(s);
vertex.weights = read<bb::vec4>(s);
vertex.weights = vertex.weights * (1.0f / (vertex.weights.x + vertex.weights.y + vertex.weights.z + vertex.weights.w));
return vertex;
}
template<> VertexPositionNormalTangentBinormalTexcoord read(istream &s)
{
VertexPositionNormalTangentBinormalTexcoord vertex;
vertex.pos = read<bb::vec4>(s);
vertex.normal = read<bb::vec3>(s);
vertex.tangent = read<bb::vec3>(s);
vertex.binormal = read<bb::vec3>(s);
vertex.texcoord = read<bb::vec2>(s);
return vertex;
}
template <typename M, typename V, typename I>
void loadGeometry(RenderingContext* context, M* mesh, std::ifstream &fin)
{
uint32_t vertexCount = read<uint32_t>(fin);
vector<V> vertices;
vertices.reserve(vertexCount);
for (unsigned v = 0; v < vertexCount; ++v)
{
vertices.push_back(read<V>(fin));
}
uint32_t indexCount = read<uint32_t>(fin);
vector<I> indices;
indices.reserve(indexCount);
for (unsigned i = 0; i < indexCount; ++i)
{
indices.push_back(read<I>(fin));
}
mesh->setGeometry(context, vertices.data(), vertices.size(), indices.data(), indices.size());
}
shared_ptr<RenderMesh> loadRenderMeshFromHappyFile(RenderingContext *pRenderContext, fs::path filePath)
{
std::ifstream fin(filePath.c_str(), std::ios::in | std::ios::binary);
uint32_t version = read<uint32_t>(fin);
version;
uint32_t type = read<uint32_t>(fin);
switch (type)
{
case 0: // static mesh
{
RenderMesh mesh;
//-------------------------------
// Geometry
loadGeometry<RenderMesh, VertexPositionNormalTangentBinormalTexcoord, Index16>(pRenderContext, &mesh, fin);
return make_shared<RenderMesh>(mesh);
}
break;
case 1: // skin mesh
{
RenderSkin mesh;
//-------------------------------
// Bind pose
uint32_t boneCount = read<uint32_t>(fin);
vector<bb::mat4> bindPose;
bindPose.reserve(boneCount);
for (unsigned b = 0; b < boneCount; ++b)
{
bb::mat4 bind = read<bb::mat4>(fin);
bind.inverse();
bindPose.push_back(bind);
}
mesh.setBindPose(pRenderContext, bindPose);
//-------------------------------
// Geometry
loadGeometry<RenderSkin, VertexPositionNormalTangentBinormalTexcoordIndicesWeights, Index16>(pRenderContext, &mesh, fin);
return make_shared<RenderSkin>(mesh);
}
break;
default:
{
throw std::exception("invalid mesh type found in .happy file");
}
break;
}
}
}