Skip to content

Commit 040589d

Browse files
committed
dae: move controller postscripts to separate file
1 parent 3b15b00 commit 040589d

File tree

5 files changed

+382
-326
lines changed

5 files changed

+382
-326
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools"
2+
"C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools",
3+
"restructuredtext.confPath": "${workspaceFolder}/docs/source"
34
}

makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ libassetkit_la_SOURCES=\
163163
src/io/dae/fixup/geom.c \
164164
src/io/dae/fixup/node.c \
165165
src/io/dae/fixup/angle.c \
166+
src/io/dae/fixup/ctlr.c \
166167
src/io/dae/core/enum.c \
167168
src/io/dae/core/color.c \
168169
src/io/dae/core/asset.c \

src/io/dae/fixup/ctlr.c

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
/*
2+
* Copyright (C) 2020 Recep Aslantas
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "ctlr.h"
18+
19+
static
20+
AK_HIDE
21+
AkResult
22+
ak_fixBoneWeights(AkHeap *heap,
23+
size_t nMeshVertex,
24+
AkSkin *skin,
25+
AkDuplicator *duplicator,
26+
AkBoneWeights *intrWeights,
27+
AkBoneWeights *weights,
28+
AkAccessor *weightsAcc,
29+
uint32_t jointOffset,
30+
uint32_t weightsOffset);
31+
32+
void AK_HIDE
33+
dae_fixup_ctlr(DAEState * __restrict dst) {
34+
AkDoc *doc;
35+
AkController *ctlr;
36+
37+
doc = dst->doc;
38+
ctlr = (void *)dst->doc->lib.controllers->chld;
39+
while (ctlr) {
40+
switch (ctlr->type) {
41+
case AK_CONTROLLER_SKIN: {
42+
AkSkin *skin;
43+
AkSkinDAE *skindae;
44+
AkGeometry *geom;
45+
46+
skin = ctlr->data;
47+
skindae = ak_userData(skin);
48+
if (!(geom = ak_baseGeometry(&skindae->baseGeom))) {
49+
goto nxt_ctlr;
50+
}
51+
52+
switch (geom->gdata->type) {
53+
case AK_GEOMETRY_MESH: {
54+
AkMesh *mesh;
55+
AkDaeMeshInfo *meshInfo;
56+
AkMeshPrimitive *prim;
57+
AkBoneWeights *intrWeights; /* interleaved */
58+
AkInput *jointswInp, *weightsInp;
59+
AkAccessor *weightsAcc;
60+
size_t nMeshVertex;
61+
uint32_t primIndex;
62+
63+
mesh = ak_objGet(geom->gdata);
64+
prim = mesh->primitive;
65+
intrWeights = (void *)skin->weights;
66+
primIndex = 0;
67+
meshInfo = rb_find(dst->meshInfo, mesh);
68+
skin->weights = ak_heap_alloc(dst->heap,
69+
ctlr->data,
70+
sizeof(void *)
71+
* mesh->primitiveCount);
72+
73+
jointswInp = skindae->weights.joints;
74+
weightsInp = skindae->weights.weights;
75+
weightsAcc = weightsInp->accessor;
76+
nMeshVertex = meshInfo->nVertex;
77+
78+
flist_sp_insert(&mesh->skins, skin);
79+
80+
while (prim) {
81+
AkAccessor *posAcc;
82+
AkBoneWeights *weights; /* per-primitive weights */
83+
AkDuplicator *dupl;
84+
size_t count;
85+
86+
posAcc = prim->pos->accessor;
87+
count = GLM_MAX(posAcc->count, 1);
88+
dupl = rb_find(doc->reserved, prim);
89+
weights = ak_heap_calloc(dst->heap, ctlr->data, sizeof(*weights));
90+
91+
weights->counts = ak_heap_alloc(dst->heap,
92+
ctlr->data,
93+
count * sizeof(uint32_t));
94+
weights->indexes = ak_heap_alloc(dst->heap,
95+
ctlr->data,
96+
count * sizeof(size_t));
97+
98+
weights->nVertex = count;
99+
100+
ak_fixBoneWeights(dst->heap,
101+
nMeshVertex,
102+
skin,
103+
dupl,
104+
intrWeights,
105+
weights,
106+
weightsAcc,
107+
jointswInp->offset,
108+
weightsInp->offset);
109+
110+
skin->weights[primIndex] = weights;
111+
primIndex++;
112+
prim = prim->next;
113+
}
114+
115+
skin->nPrims = primIndex;
116+
117+
ak_free(intrWeights);
118+
119+
break;
120+
}
121+
default:
122+
123+
124+
break;
125+
}
126+
break;
127+
}
128+
default:
129+
break;
130+
}
131+
132+
nxt_ctlr:
133+
ctlr = ctlr->next;
134+
}
135+
}
136+
137+
void AK_HIDE
138+
dae_fixup_instctlr(DAEState * __restrict dst) {
139+
AkSkinDAE *skindae;
140+
FListItem *item;
141+
AkInstanceController *instCtlr;
142+
AkController *ctlr;
143+
AkNode *node;
144+
AkInstanceGeometry *instGeom;
145+
AkContext ctx = { .doc = dst->doc };
146+
147+
item = dst->instCtlrs;
148+
while (item) {
149+
instCtlr = item->data;
150+
ctlr = ak_instanceObject(&instCtlr->base);
151+
node = instCtlr->base.node;
152+
153+
instGeom = ak_heap_calloc(dst->heap, node, sizeof(*instGeom));
154+
155+
switch (ctlr->type) {
156+
case AK_CONTROLLER_SKIN: {
157+
AkInstanceSkin *instSkin;
158+
AkSkin *skin;
159+
AkNode **joints;
160+
AkInput *jointsInp, *matrixInp;
161+
AkAccessor *jointsAcc, *matrixAcc;
162+
AkBuffer *jointsBuff, *matrixBuff;
163+
FListItem *skel;
164+
const char *sid, **it;
165+
AkFloat *mit;
166+
AkFloat4x4 *invm;
167+
size_t count, i;
168+
169+
skin = ctlr->data;
170+
skindae = ak_userData(skin);
171+
instSkin = ak_heap_calloc(dst->heap, node, sizeof(*instSkin));
172+
173+
skin = ctlr->data;
174+
jointsInp = skindae->joints.joints;
175+
matrixInp = skindae->joints.invBindMatrix;
176+
invm = NULL;
177+
joints = NULL;
178+
179+
if ((jointsAcc = jointsInp->accessor)) {
180+
matrixAcc = matrixInp->accessor;
181+
182+
jointsBuff = jointsAcc->buffer;
183+
matrixBuff = matrixAcc->buffer;
184+
185+
it = jointsBuff->data;
186+
mit = matrixBuff->data;
187+
188+
count = jointsAcc->count;
189+
joints = ak_heap_alloc(dst->heap,
190+
instCtlr,
191+
sizeof(void **) * count);
192+
193+
invm = ak_heap_alloc(dst->heap,
194+
ctlr->data,
195+
sizeof(mat4) * count);
196+
197+
for (i = 0; i < count; i++) {
198+
if (!(sid = it[i]))
199+
continue;
200+
201+
switch (jointsAcc->componentType) {
202+
case AKT_IDREF:
203+
joints[i] = ak_getObjectById(dst->doc, sid);
204+
break;
205+
case AKT_SIDREF:
206+
case AKT_NAME:
207+
if ((skel = instCtlr->reserved)) {
208+
do {
209+
if ((joints[i] = ak_sid_resolve_from(&ctx, skel->data, sid, NULL)))
210+
break;
211+
} while ((skel = skel->next));
212+
}
213+
break;
214+
default:
215+
break;
216+
}
217+
218+
/* move invBindMatrix to new location */
219+
memcpy(invm[i], mit + 16 * i, sizeof(AkFloat) * 16);
220+
glm_mat4_transpose(invm[i]);
221+
}
222+
223+
skin->nJoints = count;
224+
skin->invBindPoses = invm;
225+
226+
instSkin->skin = skin;
227+
instSkin->overrideJoints = joints;
228+
229+
/* create instance geometry for skin */
230+
instGeom->skinner = instSkin;
231+
instGeom->bindMaterial = instCtlr->bindMaterial;
232+
instGeom->base.object = skindae->baseGeom.ptr;
233+
ak_heap_setpm(instCtlr->bindMaterial, instGeom);
234+
235+
instGeom->base.next = (AkInstanceBase *)node->geometry;
236+
if (node->geometry)
237+
node->geometry->base.prev = (AkInstanceBase *)instGeom;
238+
node->geometry = instGeom;
239+
}
240+
}
241+
default: break;
242+
}
243+
item = item->next;
244+
}
245+
}
246+
247+
static
248+
AK_HIDE
249+
AkResult
250+
ak_fixBoneWeights(AkHeap *heap,
251+
size_t nMeshVertex,
252+
AkSkin *skin,
253+
AkDuplicator *duplicator,
254+
AkBoneWeights *intrWeights,
255+
AkBoneWeights *weights,
256+
AkAccessor *weightsAcc,
257+
uint32_t jointOffset,
258+
uint32_t weightsOffset) {
259+
AkSkinDAE *skindae;
260+
AkBoneWeight *w, *iw;
261+
AkBuffer *weightsBuff;
262+
AkUIntArray *dupc, *dupcsum, *v;
263+
float *pWeights;
264+
uint32_t *pv, *pOldCount, *pOldCountSum;
265+
size_t *wi, vc, d, s, pno, poo, nwsum, newidx, next, tmp;
266+
uint32_t *nj, i, j, k, vcount, count, viStride;
267+
268+
dupc = duplicator->range->dupc;
269+
dupcsum = duplicator->range->dupcsum;
270+
vc = nMeshVertex;
271+
nj = weights->counts;
272+
wi = weights->indexes;
273+
skindae = ak_userData(skin);
274+
nwsum = count = 0;
275+
276+
if (!(weightsBuff = weightsAcc->buffer)
277+
|| !(pWeights = weightsBuff->data)
278+
|| !(v = skindae->weights.v)
279+
|| !(pv = v->items))
280+
return AK_ERR;
281+
282+
#ifdef DEBUG
283+
assert(nMeshVertex == intrWeights->nVertex);
284+
#endif
285+
286+
pOldCount = intrWeights->counts;
287+
pOldCountSum = intrWeights->counts + intrWeights->nVertex;
288+
viStride = skindae->inputCount; /* input count in <v> element */
289+
290+
/* copy to new location and duplicate if needed */
291+
for (i = 0; i < vc; i++) {
292+
if ((poo = dupc->items[3 * i + 2]) == 0)
293+
continue;
294+
295+
pno = dupc->items[3 * i];
296+
d = dupc->items[3 * i + 1];
297+
s = dupcsum->items[pno];
298+
vcount = pOldCount[poo - 1];
299+
300+
for (j = 0; j <= d; j++) {
301+
newidx = pno + j + s;
302+
wi[newidx] = vcount;
303+
nj[newidx] = vcount;
304+
}
305+
306+
nwsum += vcount * (d + 1);
307+
count++;
308+
}
309+
310+
/* prepare weight index */
311+
for (next = j = 0; j < weights->nVertex; j++) {
312+
tmp = wi[j];
313+
wi[j] = next;
314+
next = tmp + next;
315+
}
316+
317+
/* now we know the size of arrays: weights, pJointsCount, npWeightsIndex */
318+
w = ak_heap_alloc(heap, weights, sizeof(*w) * nwsum);
319+
nwsum = 0;
320+
321+
for (i = 0; i < vc; i++) {
322+
uint32_t *old;
323+
324+
if ((poo = dupc->items[3 * i + 2]) == 0)
325+
continue;
326+
327+
pno = dupc->items[3 * i];
328+
d = dupc->items[3 * i + 1];
329+
s = dupcsum->items[pno];
330+
vcount = pOldCount[poo - 1];
331+
old = &pv[pOldCountSum[poo - 1] * viStride];
332+
333+
for (j = 0; j <= d; j++) {
334+
newidx = wi[pno + j + s];
335+
336+
for (k = 0; k < vcount; k++) {
337+
iw = &w[newidx + k];
338+
iw->joint = old[k * viStride + jointOffset];
339+
iw->weight = pWeights[old[k * viStride + weightsOffset]];
340+
}
341+
}
342+
343+
nwsum += vcount * (d + 1);
344+
}
345+
346+
weights->weights = w;
347+
weights->nWeights = nwsum;
348+
349+
return AK_OK;
350+
}

src/io/dae/fixup/ctlr.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2020 Recep Aslantas
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef dae_ctlr_h
18+
#define dae_ctlr_h
19+
20+
#include "../common.h"
21+
22+
void AK_HIDE
23+
dae_fixup_ctlr(DAEState * __restrict dst);
24+
25+
void AK_HIDE
26+
dae_fixup_instctlr(DAEState * __restrict dst);
27+
28+
#endif /* dae_ctlr_h */

0 commit comments

Comments
 (0)