12#include "FgTestUtils.hpp"
15#include "Fg3dMeshIo.hpp"
17#include "Fg3Freeform.hpp"
20#include "Fg3dDisplay.hpp"
28void endianFlip_(uint16 & v)
30 uchar *ptr =
reinterpret_cast<uchar*
>(&v);
33void endianFlip_(uint32 & v)
35 uchar *ptr =
reinterpret_cast<uchar*
>(&v);
39void endianFlip_(
float & v)
41 uchar *ptr =
reinterpret_cast<uchar*
>(&v);
46inline T endianFlip(T v) {endianFlip_(v);
return v; }
48struct DnaSectionLookup
55 uint32 blendShapeChannels;
60void checkSig_(Bytes
const & blob,
size_t & pos)
62 Arr3UC sig = dsrlzT_<Arr3UC>(blob,pos);
63 if (sig != Arr3UC{
'D',
'N',
'A'})
64 fgThrow(
"not a DNA file");
65 uint16 verMaj = endianFlip(dsrlzT_<uint16>(blob,pos)),
66 verMin = endianFlip(dsrlzT_<uint16>(blob,pos));
68 fgThrow(
"unsupported DNA file major version",toStr(verMaj));
70 fgWarn(
"unsupported DNA file minor versino",toStr(verMin));
74T get_(Bytes
const & blob,
size_t & pos) {
return endianFlip(dsrlzT_<T>(blob,pos)); }
77Uints gets_(Bytes
const & blob,
size_t & pos)
79 size_t sz = get_<uint32>(blob,pos);
80 Uints ret; ret.reserve(sz);
81 for (
size_t ii=0; ii<sz; ++ii)
82 ret.push_back(get_<T>(blob,pos));
86DnaSectionLookup getDsl(Bytes
const & blob,
size_t & pos)
88 auto get32 = [&](){
return get_<uint32>(blob,pos); };
90 dsl.descriptor = get32();
91 dsl.definition = get32();
92 dsl.behavior = get32();
93 dsl.controls = get32();
95 dsl.blendShapeChannels = get32();
96 dsl.animateMaps = get32();
97 dsl.geometry = get32();
101Vec2Fs getVec2Fs_(Bytes
const & blob,
size_t & pos)
103 uint32 sz = get_<uint32>(blob,pos);
105 for (
size_t vv=0; vv<sz; ++vv)
106 vecs[vv][0] = get_<float>(blob,pos);
107 FGASSERT(get_<uint32>(blob,pos) == sz);
108 for (
size_t vv=0; vv<sz; ++vv)
109 vecs[vv][1] = get_<float>(blob,pos);
113Vec3Fs getVec3Fs_(Bytes
const & blob,
size_t & pos)
115 auto get32 = [&](){
return get_<uint32>(blob,pos); };
116 auto getFlt = [&](){
return get_<float>(blob,pos); };
119 for (
size_t vv=0; vv<sz; ++vv)
120 vecs[vv][0] = getFlt();
121 FGASSERT(get32() == sz);
122 for (
size_t vv=0; vv<sz; ++vv)
123 vecs[vv][1] = getFlt();
124 FGASSERT(get32() == sz);
125 for (
size_t vv=0; vv<sz; ++vv)
126 vecs[vv][2] = getFlt();
133Meshes dnaImport(Bytes
const & blob)
138 auto get16 = [&](){
return get_<uint16>(blob,pos); };
139 auto get32 = [&](){
return get_<uint32>(blob,pos); };
140 auto get16s = [&](){
return gets_<uint16>(blob,pos); };
141 auto get32s = [&](){
return gets_<uint32>(blob,pos); };
142 auto getVec2Fs = [&](){
return getVec2Fs_(blob,pos); };
143 auto getVec3Fs = [&](){
return getVec3Fs_(blob,pos); };
144 auto getVertInds = [&](Vec3UIs & tris,Vec4UIs & quads)
147 for (
size_t ii=0; ii<sz; ++ii) {
148 uint32 len = get32();
151 for (
size_t jj=0; jj<3; ++jj)
157 for (
size_t jj=0; jj<4; ++jj)
162 fgThrow(
"unhandled polygon size",toStr(len));
165 auto getLodInds = [&]()
167 Uints lods = get16s();
170 for (Uints & row : ret)
174 auto getStrings = [&]()
178 for (String & str : ret) {
180 FGASSERT(pos+ss <= blob.size());
181 str = String{
reinterpret_cast<char const *
>(&blob[pos]),ss};
186 DnaSectionLookup dsl = getDsl(blob,pos);
187 pos = dsl.definition;
189 Uintss jointLodInds = getLodInds(),
190 blendLodInds = getLodInds(),
191 animLodInds = getLodInds(),
192 meshLodInds = getLodInds();
193 Strings guiControlNames = getStrings(),
194 rawControlNames = getStrings(),
195 jointNames = getStrings(),
196 blendShapeChannelNames = getStrings(),
197 animatedMapNames = getStrings(),
198 meshNames = getStrings();
200 uint32 numMeshes = get32();
201 FGASSERT(numMeshes == meshNames.size());
202 for (
size_t mm=0; mm<numMeshes; ++mm) {
203 uint32 offset = get32();
204 Vec3Fs verts = getVec3Fs();
205 Vec2Fs uvs = getVec2Fs();
206 Vec3Fs norms = getVec3Fs();
207 Uints vertList = get32s(),
210 size_t listSz = vertList.size();
211 FGASSERT(uvList.size() == listSz);
212 FGASSERT(normList.size() == listSz);
215 getVertInds(triInds,quadInds);
218 TriInds tInds; tInds.reserve(triInds.size());
219 for (Vec3UI tri : triInds) {
220 tInds.vertInds.emplace_back(vertList[tri[0]],vertList[tri[1]],vertList[tri[2]]);
221 tInds.uvInds.emplace_back(uvList[tri[0]],uvList[tri[1]],uvList[tri[2]]);
223 QuadInds qInds; qInds.reserve(quadInds.size());
224 for (Vec4UI q : quadInds) {
225 qInds.vertInds.emplace_back(vertList[q[0]],vertList[q[1]],vertList[q[2]],vertList[q[3]]);
226 qInds.uvInds.emplace_back(uvList[q[0]],uvList[q[1]],uvList[q[2]],uvList[q[3]]);
228 Strings names = splitChar(meshNames[mm],
'_');
229 String name = names[1] +
'-' + names[0];
230 ret.push_back(Mesh{name,verts,uvs,{Surf{tInds,qInds}}});
236void dnaInject_(Vec3Fss
const & shapes,Bytes & blob)
240 auto get32 = [&](){
return get_<uint32>(blob,pos); };
241 DnaSectionLookup dsl = getDsl(blob,pos);
243 uint32 numMeshes = get32();
244 if (numMeshes != shapes.size())
245 fgThrow(
"number of vertex lists to inject differ from dna mesh count",toStr(shapes.size())+
"!="+toStr(numMeshes));
246 for (
size_t mm=0; mm<numMeshes; ++mm) {
247 Vec3Fs
const & shape = shapes[mm];
248 uint32 offset = get32();
249 for (uint jj=0; jj<3; ++jj) {
251 if (sz != shape.size())
252 fgThrow(
"vertex count differs for mesh",toStr(mm));
253 for (
size_t vv=0; vv<sz; ++vv) {
254 float v = shape[vv][jj];
255 byte *ptr =
reinterpret_cast<byte*
>(&v);
258 memcpy(&blob[pos],ptr,4);