Pages: 1
Posted on 01-16-17, 03:18 pm (rev. 3 by RicBent on 01-16-17, 03:21 pm)
Mariomaster

Karma: 8528
Posts: 787/1681
Since: 06-09-12
Well this is mostly a findings dump. All functions beneath are though enough to draw (animated) 3d models.
Still it might not be as detailed as needed to make it usable for everyone.

Here we go:


NSMB makes it very easy for us. We only need to call 3 functions to get everything going.

If you want to draw a model alongside a actor you have to place the corresponding struct in it's alloced memory.
What exactly each part of the following structs do is not known, but not necessary.

typedef struct  // Size: 0x90
{
        u32 unk[0x24];
} Model3d;

typedef struct  // Size: 0x18
{
        u32 unk[0x6];
} Anim3d;

typedef struct  // Size: 0xA8
{
        Model3d model;  // 0x00
        Anim3d anim;    // 0x90
} ModelAnim3d;

Use Model3d if you want an unanimated model, use ModelAnim3d if you want an animated model.


Now the functions:

// Functions for Models without animation
void model3d_ctor(Model3d* model);
bool model3d_setup(Model3d* model, void* modelFile, u32 unk);
void model3d_init(Model3d* model);
       
// Functions for Models with character animation
// These functions call all above functions
void modelAnim3d_ctor(ModelAnim3d* model);
bool modelAnim3d_setup(ModelAnim3d* model, void* modelFile, void* animationFile, u32 unk1 , u32 unk2, u32 unk3);
void modelAnim3d_init(Model3d* model, u32 animationId, u32 unk1, u32 animationSpeed, u32 unk2);

void anim3d_update(Anim3d* animation);


Call the corresponding _ctor function in the constructor of you actor.
Then _setup and then _init in onCreate if your actor. _setup is normally called in heapCreated, but that sometimes causes strange crashes.

For changing the animation recall _init on the animated modell.
To update the animation call anim3d_update on the modelAnim3d.anim somewhere in onExecute.


Finally the custom onDraw function. This is custom and made by REing existing sprites:

CustomActor_onDraw:    
       
        STMFD   SP!, {R4,LR}
        MOV     R4, R0
       
       
        @ Set Position
        LDR     R0, =0x0208B6E8
        LDR     R1, [R4,#0x60]   @ Adress of the X Position
        LDR     R2, [R4,#0x64]   @ Adress of the Y Position
        LDR     R3, [R4,#0x68]   @ Adress of the Z Position
        BL      SetModelPos
       
        @ Set Rotation
        LDR     R0, =0x0208B6E8
        LDRSH   R1, [R4,#0xA0]  @ Adress of the X Rotation
        BL      SetModelRotX
       
        LDR     R0, =0x0208B6E8
        LDRSH   R1, [R4,#0xA2]  @ Adress of the Y Rotation
        BL      SetModelRotY
       
        LDR     R0, =0x0208B6E8
        LDRSH   R1, [R4,#0xA4]  @ Adress of the Z Rotation
        BL      SetModelRotZ
       
        LDR     LR, =0x0208B6E8
        LDR     R12, =0x454
        LDMIA   LR!, {R0-R3}
        ADD     R12, R4, R12
        STMIA   R12!, {R0-R3}
        LDMIA   LR!, {R0-R3}
        STMIA   R12!, {R0-R3}
        LDMIA   LR, {R0-R3}
        STMIA   R12, {R0-R3}
       
        ADD     R0, R4, #0x3F4  @ Adress of the Model
        ADD     R1, R4, #0xF0   @ Adress of the Scale Vec3
        LDR     R2, [R0]
        LDR     R2, [R2,#0xC]
        BLX     R2

        MOV     R0, #1
        LDMFD   SP!, {R4,PC}



These are the adresses of the found functions (for symbols.x):

model3d_ctor = 0x2019A30;
model3d_setup = 0x2019948;
model3d_init = 0x2019A30;

modelAnim3d_ctor = 0x2019644;
modelAnim3d_setup = 0x2019530;
modelAnim3d_init = 0x2019440;

anim3d_update = 0x201FEB8;

SetModelPos = 0x2044814;
SetModelRotX = 0x20448B4;
SetModelRotY = 0x2044888;
SetModelRotZ = 0x204485C;



(Oh, the function names I came up with might be entirely senseless. I didn't re what exactly they do. I simply looked at a lot of actors to see how they do it)
_________________________
GitHub - Kuribo64 - YouTube
Pages: 1