forked from TomohikoMukai/ssdr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.cpp
127 lines (117 loc) · 3.37 KB
/
util.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
118
119
120
121
122
123
124
125
126
127
#include "util.h"
#include <cstdio>
static const char* delim = " /\t\n";
static char* context = nullptr;
using namespace DirectX;
bool ReadVector3(XMFLOAT3& v, char* buf)
{
// local definition
//
#define READ_VECTOR3_TOKEN(ELEMENT) tok = strtok_s(buf, delim, &context); \
if (tok == nullptr) { return false; } \
v.ELEMENT = static_cast<float>(std::atof(tok));
//
char* tok = nullptr;
READ_VECTOR3_TOKEN(x);
READ_VECTOR3_TOKEN(y);
READ_VECTOR3_TOKEN(z);
return true;
}
bool LoadObjFile(std::vector<XMFLOAT3A>& position, std::vector<DWORD>& index, const std::wstring& filePath, float scale)
{
char buf[1024];
char* tok = nullptr;
FILE* fin = nullptr;
_wfopen_s(&fin, filePath.data(), L"r");
if (fin == nullptr)
{
return false;
}
position.clear();
index.clear();
while (std::fgets(buf, 1024, fin) != nullptr)
{
tok = strtok_s(buf, delim, &context);
if (tok == nullptr)
{
}
else if (tok[0] == '#')
{
continue;
}
else if (strcmp(tok, "v") == 0)
{
XMFLOAT3 p;
if (!ReadVector3(p, NULL))
{
break;
}
position.push_back(XMFLOAT3A(p.x * scale, p.y * scale, p.z * scale));
}
else if (strcmp(tok, "vt") == 0)
{
continue;
}
else if (strcmp(tok, "f") == 0)
{
std::vector<unsigned int > tmp;
while (tok = strtok_s(NULL, delim, &context), tok != nullptr)
{
tmp.push_back(static_cast<unsigned int >(atol(tok) - 1));
}
switch (tmp.size())
{
case 6:
index.push_back(tmp[0]);
index.push_back(tmp[2]);
index.push_back(tmp[4]);
break;
default:
fclose(fin);
position.clear();
index.clear();
return false;
break;
}
}
else if (strcmp(tok, "g") == 0)
{
continue;
}
else
{
continue;
}
}
fclose(fin);
return true;
}
bool ComputeNormal(std::vector<XMFLOAT3A>& normal, const std::vector<XMFLOAT3A>& position, const std::vector<DWORD>& index)
{
if (position.empty() || index.empty())
{
return false;
}
std::vector<XMFLOAT3A> nv(position.size(), XMFLOAT3A(0, 0, 0));
for (auto it = index.begin(); it != index.end(); it += 3)
{
const XMVECTOR v0 = XMLoadFloat3A(&position[*it]);
const XMVECTOR v1 = XMLoadFloat3A(&position[*(it + 1)]);
const XMVECTOR v2 = XMLoadFloat3A(&position[*(it + 2)]);
XMVECTOR n = XMVector3Cross(XMVectorSubtract(v1, v0), XMVectorSubtract(v2, v0));
n = XMVector3Normalize(n);
XMStoreFloat3A(&nv[*it], XMVectorAdd(XMLoadFloat3A(&nv[*it]), n));
XMStoreFloat3A(&nv[*(it + 1)], XMVectorAdd(XMLoadFloat3A(&nv[*(it + 1)]), n));
XMStoreFloat3A(&nv[*(it + 2)], XMVectorAdd(XMLoadFloat3A(&nv[*(it + 2)]), n));
}
normal.resize(position.size());
for (size_t v = 0; v < position.size(); ++v)
{
XMVECTOR n = XMLoadFloat3A(&nv[v]);
n = XMVector3Normalize(n);
XMFLOAT3A na;
XMStoreFloat3A(&na, n);
normal[v] = na;
}
return true;
}