Skip to content

Commit 244db42

Browse files
authored
iModel work (bfbbdecomp#619)
1 parent 0bf7636 commit 244db42

File tree

2 files changed

+306
-20
lines changed

2 files changed

+306
-20
lines changed

src/SB/Core/gc/iModel.cpp

Lines changed: 299 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
11
#include "iModel.h"
22

33
#include <types.h>
4+
#include <rpskin.h>
5+
#include <rpmatfx.h>
6+
47
#include "zAssetTypes.h"
8+
#include "xMathInlines.h"
9+
10+
extern RwGlobals* RwEngineInstance;
11+
static RpAtomic* sLastMaterial;
12+
static U32 sMaterialFlags;
13+
static U32 sMaterialIdx;
14+
static RwTexture* sMaterialTexture[16];
15+
static U32 gLastAtomicCount;
16+
static RpAtomic* gLastAtomicList[256];
17+
18+
static RpLight* sEmptyDirectionalLight[4];
19+
static RpLight* sEmptyAmbientLight;
20+
21+
int iModelHack_DisablePrelight;
522

623
RwFrame* GetChildFrameHierarchy(RwFrame* frame, void* data)
724
{
825
RpHAnimHierarchy* hierarchy = RpHAnimFrameGetHierarchy(frame);
926
if (hierarchy == 0)
1027
{
11-
RwFrameForAllChildren(frame, GetChildFrameHierarchy, data);
28+
RwFrameForAllChildren(frame, &GetChildFrameHierarchy, data);
29+
return frame;
1230
}
1331
else
1432
{
15-
data = hierarchy;
33+
*(RpHAnimHierarchy**)data = hierarchy;
1634
frame = 0;
1735
}
1836
return frame;
@@ -26,51 +44,312 @@ void* GetHierarchy(RpAtomic* frame)
2644
return unk_0[0];
2745
}
2846

47+
void iModelInit()
48+
{
49+
RwRGBAReal black = { 0.0f, 0.0f, 0.0f, 0.0f };
50+
if (sEmptyDirectionalLight[0] == 0)
51+
{
52+
for (int i = 0; i < (int)(sizeof(sEmptyDirectionalLight) / sizeof(RpLight*)); i++)
53+
{
54+
sEmptyDirectionalLight[i] = RpLightCreate(rpLIGHTDIRECTIONAL);
55+
RpLightSetColor(sEmptyDirectionalLight[i], &black);
56+
RwFrame* frame = RwFrameCreate();
57+
_rwObjectHasFrameSetFrame(sEmptyDirectionalLight[i], frame);
58+
}
59+
sEmptyAmbientLight = RpLightCreate(rpLIGHTAMBIENT);
60+
RpLightSetColor(sEmptyAmbientLight, &black); // Redundant sEmptyAmbientLight load here.
61+
}
62+
}
63+
64+
RpAtomic* FindAndInstanceAtomicCallback(RpAtomic* model, void* data)
65+
{
66+
RpHAnimHierarchy* hierarchy = (RpHAnimHierarchy *)GetHierarchy(model);
67+
RpGeometry* geom = model->geometry;
68+
RpSkin* skin = RpSkinGeometryGetSkin(geom);
69+
70+
if ((skin != NULL) && (hierarchy == NULL))
71+
{
72+
hierarchy = (RpHAnimHierarchy *)RpHAnimHierarchyCreate(RpSkinGetNumBones(skin), 0, 0, rpHANIMHIERARCHYLOCALSPACEMATRICES, 0x24);
73+
RpHAnimFrameSetHierarchy((RwFrame*)(model->object).object.parent, hierarchy);
74+
}
75+
if ((hierarchy != NULL) && (skin != NULL))
76+
{
77+
RpSkinAtomicSetHAnimHierarchy(model,hierarchy);
78+
}
79+
if (hierarchy != NULL)
80+
{
81+
hierarchy->flags = 0x4000;
82+
}
83+
if (gLastAtomicCount < 0x100)
84+
{
85+
gLastAtomicList[gLastAtomicCount] = model;
86+
gLastAtomicCount++;
87+
}
88+
89+
RwFrame* root = RwFrameGetRoot((RwFrame*)(model->object).object.parent);
90+
RpMaterialList* matList = &geom->matList;
91+
int numMats = matList->numMaterials;
92+
93+
for (int i = 0; i < numMats; i++)
94+
{
95+
RpMaterial *pRVar4 = (RpMaterial *)_rpMaterialListGetMaterial(matList, i);
96+
if ((pRVar4 != NULL) && (RpMatFXMaterialGetEffects(pRVar4) != 0))
97+
{
98+
RpMatFXAtomicEnableEffects(model);
99+
model->pipeline = (RxPipeline *)RpMatFXGetGameCubePipeline(rpMATFXGAMECUBEATOMICPIPELINE);
100+
if (RpSkinGeometryGetSkin(geom) != 0)
101+
{
102+
RpSkinAtomicSetType(model, rpSKINTYPEMATFX);
103+
}
104+
break;
105+
}
106+
}
107+
108+
if (gLastAtomicCount < 0x100)
109+
{
110+
gLastAtomicList[gLastAtomicCount] = model;
111+
gLastAtomicCount++;
112+
}
113+
114+
return model;
115+
}
116+
29117
RpAtomic* iModelFileNew(void* buffer, U32 size)
30118
{
31119
RwMemory rwmem;
120+
rwmem.start = (U8*)buffer;
121+
rwmem.length = size;
32122

33-
return iModelStreamRead(RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &buffer));
123+
return iModelStreamRead(RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &rwmem));
34124
}
35125

36126
void iModelUnload(RpAtomic* userdata)
37127
{
38-
// Not really a hard function.
39-
// Don't know why frame and root exist
40128
RpClump* clump;
41-
RwFrame* frame;
42129
RwFrame* root;
130+
RwFrame* frame;
43131

44132
clump = userdata->clump;
45-
if (clump->object.parent != 0)
133+
frame = (RwFrame*)(clump->object).parent;
134+
if (frame != 0)
46135
{
47-
RwFrameGetRoot((RwFrame*)userdata->object.object.parent);
48-
RwFrameDestroyHierarchy((RwFrame*)clump);
49-
userdata->object.object.parent = 0;
136+
root = (RwFrame*)RwFrameGetRoot(frame);
137+
if (root != 0)
138+
{
139+
frame = root;
140+
}
141+
RwFrameDestroyHierarchy(frame);
142+
clump->object.parent = 0;
50143
}
51-
if (&clump->object != 0)
144+
if (clump != 0)
52145
{
53146
RpClumpDestroy(clump);
54147
}
55148
}
56149

57150
static RpAtomic* NextAtomicCallback(RpAtomic* atomic, void* data)
58151
{
59-
RpAtomic** nextModel;
60-
61-
if (data == atomic)
152+
if (*(U32*)data == (U32)atomic)
62153
{
63-
data = 0;
64-
return (RpAtomic*)data;
154+
*(U32*)data = 0;
65155
}
66-
if (data == 0)
156+
else if (*(U32*)data == 0)
67157
{
68-
return atomic;
158+
*(RpAtomic **)data = atomic;
69159
}
70-
data = atomic;
71160
return atomic;
72161
}
73162

74-
void iModelCacheAtomic(RpAtomic*)
163+
RpAtomic* iModelFile_RWMultiAtomic(RpAtomic* model)
164+
{
165+
RpClump* clump;
166+
RpAtomic* nextModel;
167+
168+
if (model == 0)
169+
{
170+
return 0;
171+
}
172+
else
173+
{
174+
clump = model->clump;
175+
nextModel = model;
176+
RpClumpForAllAtomics(clump, NextAtomicCallback, &nextModel);
177+
return nextModel;
178+
}
179+
}
180+
181+
U32 iModelNumBones(RpAtomic* model)
182+
{
183+
RpHAnimHierarchy* obj = (RpHAnimHierarchy*)GetHierarchy(model);
184+
return obj != 0 ? (U32)obj->numNodes : 0;
185+
}
186+
187+
void iModelQuatToMat(xQuat* q, xVec3* a, RwMatrixTag* t)
188+
{
189+
q->s = -q->s;
190+
xQuatToMat(q, (xMat3x3*)t);
191+
q->s = -q->s;
192+
t->pos.x = a->x;
193+
t->pos.y = a->y;
194+
t->pos.z = a->z;
195+
}
196+
197+
// WIP
198+
void iModelAnimMatrices(RpAtomic* model, xQuat* quat, xVec3* tran, RwMatrixTag* mat)
199+
{
200+
RwMatrixTag* pMatrixArray;
201+
RpHAnimNodeInfo* iVar1;
202+
RwMatrixTag matrixStack [33];
203+
U32 pCurrentFrameFlags;
204+
RpHAnimNodeInfo* pCurrentFrame;
205+
int numFrames;
206+
RwMatrixTag* pMatrixStackTop;
207+
208+
pCurrentFrame = (RpHAnimNodeInfo *)GetHierarchy(model);
209+
210+
if (pCurrentFrame != NULL)
211+
{
212+
pMatrixStackTop = &matrixStack[0];
213+
pMatrixStackTop->at.z = 1.0;
214+
215+
matrixStack[0].up.y = 1.0;
216+
matrixStack[0].right.x = 1.0;
217+
matrixStack[0].up.x = 0.0;
218+
matrixStack[0].right.z = 0.0;
219+
matrixStack[0].right.y = 0.0;
220+
matrixStack[0].at.y = 0.0;
221+
matrixStack[0].at.x = 0.0;
222+
matrixStack[0].up.z = 0.0;
223+
matrixStack[0].pos.z = 0.0;
224+
matrixStack[0].pos.y = 0.0;
225+
matrixStack[0].pos.x = 0.0;
226+
matrixStack[0].flags |= 0x20003;
227+
228+
matrixStack[1] = matrixStack[0];
229+
numFrames = pCurrentFrame->nodeIndex;
230+
pMatrixArray = (&matrixStack[1]);
231+
iVar1 = (RpHAnimNodeInfo *)pCurrentFrame[1].nodeID;
232+
233+
pMatrixArray++;
234+
for (int i = 0; i < numFrames; i++)
235+
{
236+
pCurrentFrameFlags = iVar1->flags;
237+
if ((pCurrentFrameFlags & 2) != 0)
238+
{
239+
*pMatrixArray++ = matrixStack[0];
240+
}
241+
242+
RwMatrixTag afStack_8e8;
243+
iModelQuatToMat(quat, tran, &afStack_8e8);
244+
245+
RwMatrixTag auStack_8a8;
246+
xMat4x3Mul((xMat4x3*)&auStack_8a8,(xMat4x3*)&afStack_8e8, (xMat4x3*)&matrixStack[0]);
247+
248+
*mat = auStack_8a8;
249+
if ((pCurrentFrameFlags & 1) != 0)
250+
{
251+
pMatrixArray = &pMatrixArray[-1];
252+
pMatrixStackTop = pMatrixArray;
253+
}
254+
else
255+
{
256+
pMatrixStackTop = (RwMatrixTag *)&auStack_8a8;
257+
}
258+
matrixStack[0] = *pMatrixStackTop;
259+
mat++;
260+
quat++;
261+
tran++;
262+
iVar1++;
263+
}
264+
}
265+
}
266+
267+
RpAtomic* iModelCacheAtomic(RpAtomic* model)
75268
{
269+
return model;
76270
}
271+
272+
void iModelRender(RpAtomic* model, RwMatrixTag* mat)
273+
{
274+
RpHAnimHierarchy* hierarchy;
275+
RpGeometry* geom;
276+
RwMatrixTag* pAnimOldMatrix;
277+
RwFrame* frame;
278+
279+
hierarchy = (RpHAnimHierarchy*)GetHierarchy(model);
280+
281+
static S32 draw_all = 1;
282+
283+
if (hierarchy != NULL)
284+
{
285+
pAnimOldMatrix = hierarchy->pMatrixArray;
286+
hierarchy->pMatrixArray = mat + 1;
287+
}
288+
frame = (RwFrame*)model->object.object.parent;
289+
frame->ltm = *mat;
290+
RwMatrixUpdate(&frame->ltm);
291+
if (iModelHack_DisablePrelight != 0)
292+
{
293+
model->geometry->flags &= 0xfffffff7;
294+
}
295+
iModelCacheAtomic(model)->renderCallBack(iModelCacheAtomic(model));
296+
if ((iModelHack_DisablePrelight != 0) && (model->geometry->preLitLum != NULL))
297+
{
298+
model->geometry->flags |= 8;
299+
}
300+
if (hierarchy != NULL)
301+
{
302+
hierarchy->pMatrixArray = pAnimOldMatrix;
303+
}
304+
}
305+
306+
S32 iModelSphereCull(const xSphere* sphere)
307+
{
308+
return RwCameraFrustumTestSphere((const RwCamera*)RwEngineInstance->curCamera, (const RwSphere*)sphere) == 0;
309+
}
310+
311+
U32 iModelVertCount(RpAtomic *model)
312+
{
313+
return model->geometry->numVertices;
314+
}
315+
316+
void iModelResetMaterial(RpAtomic* model)
317+
{
318+
RpAtomic* material = sLastMaterial; // r2
319+
RpGeometry* geom; // r21
320+
321+
if (model != material)
322+
{
323+
sMaterialFlags = 0;
324+
}
325+
326+
geom = model->geometry;
327+
328+
sMaterialIdx = 0;
329+
RpGeometryForAllMaterials(geom, iModelResetMaterialCB, 0);
330+
sMaterialFlags = 0;
331+
}
332+
333+
RpMaterial* iModelSetMaterialTextureCB(RpMaterial* material, void* data)
334+
{
335+
int i = sMaterialIdx;
336+
RwTexture* texture = material->texture;
337+
sMaterialIdx++;
338+
sMaterialTexture[i] = texture;
339+
RpMaterialSetTexture(material, (RwTexture*)data);
340+
return material;
341+
}
342+
343+
void iModelSetMaterialTexture(RpAtomic* model, void* texture)
344+
{
345+
RpGeometry* geom;
346+
if (model != sLastMaterial)
347+
{
348+
sMaterialFlags = 0;
349+
}
350+
geom = model->geometry;
351+
sMaterialIdx = 0;
352+
RpGeometryForAllMaterials(geom, iModelSetMaterialTextureCB, texture);
353+
sMaterialFlags |= 4;
354+
sLastMaterial = model;
355+
}

src/SB/Core/gc/iModel.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
#include <rphanim.h>
1010

1111
void iModelInit();
12+
static RpAtomic* FindAndInstanceAtomicCallback(RpAtomic* model, void* data);
13+
static RpAtomic* iModelCacheAtomic(RpAtomic*);
14+
RpMaterial* iModelResetMaterialCB(RpMaterial*, void*);
15+
static void* GetHierarchy(RpAtomic* frame);
16+
static RwFrame* GetChildFrameHierarchy(RwFrame* frame, void* data);
1217
U32 iModelNumBones(RpAtomic* model);
1318
S32 iModelCull(RpAtomic* model, RwMatrixTag* mat);
1419
S32 iModelSphereCull(xSphere* sphere);
@@ -18,6 +23,7 @@ RpAtomic* iModelFile_RWMultiAtomic(RpAtomic* model);
1823
void iModelSetMaterialTexture(RpAtomic* model, void* texture);
1924
void iModelResetMaterial(RpAtomic* model);
2025
void iModelUnload(RpAtomic* userdata);
26+
static RpAtomic* NextAtomicCallback(RpAtomic* atomic, void* data);
2127
S32 iModelCullPlusShadow(RpAtomic* model, RwMatrix* mat, xVec3* shadowVec, S32* shadowOutside);
2228
void iModelTagEval(RpAtomic* model, const xModelTag* tag, RwMatrixTag* mat, xVec3* dest);
2329
U32 iModelTagSetup(xModelTag* tag, RpAtomic* model, F32 x, F32 y, F32 z);
@@ -28,5 +34,6 @@ RpAtomic* iModelFileNew(void* buffer, U32 size);
2834
void iModelRender(RpAtomic* model, RwMatrix* mat);
2935
void iModelUnload(RpAtomic* userdata);
3036
void iModelAnimMatrices(RpAtomic* model, xQuat* quat, xVec3* tran, RwMatrixTag* mat);
37+
static RpMaterial* iModelSetMaterialTextureCB(RpMaterial* material, void* data);
3138

3239
#endif

0 commit comments

Comments
 (0)