//
// Generated by dtk
// Translation Unit: J3DShapeMtx.cpp
//

#include "JSystem/J3DGraphBase/J3DShapeMtx.h"
#include "JSystem/J3DGraphBase/J3DGD.h"
#include "JSystem/J3DGraphBase/J3DPacket.h"
#include "JSystem/J3DGraphBase/J3DShapeDraw.h"
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/J3DGraphBase/J3DTransform.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/J3DGraphAnimator/J3DModelData.h"

extern void J3DFifoLoadNrmMtxImm(Mtx, u32);
extern void J3DFifoLoadNrmMtxImm3x3(Mtx33, u32);
extern void J3DFifoLoadPosMtxImm(Mtx, u32);

u32 J3DShapeMtx::sCurrentPipeline;

/* 802DB9D8-802DBA1C       .text loadMtxIndx_PNGP__11J3DShapeMtxCFiUs */
void J3DShapeMtx::loadMtxIndx_PNGP(int mtxNo, u16 index) const {
    J3DFifoLoadIndx(GX_CMD_LOAD_INDX_A, index, 0xB000 | ((u16)(mtxNo * 0x0C)));
    J3DFifoLoadIndx(GX_CMD_LOAD_INDX_B, index, 0x8000 | ((u16)((mtxNo * 0x09) + 0x400)));
}

/* 802DBA1C-802DBA7C       .text loadMtxIndx_PCPU__11J3DShapeMtxCFiUs */
void J3DShapeMtx::loadMtxIndx_PCPU(int mtxNo, u16 index) const {
    J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
    j3dSys.loadNrmMtxIndx(mtxNo, index);
}

/* 802DBA7C-802DBAC8       .text loadMtxIndx_NCPU__11J3DShapeMtxCFiUs */
void J3DShapeMtx::loadMtxIndx_NCPU(int mtxNo, u16 index) const {
    j3dSys.loadPosMtxIndx(mtxNo, index);
    J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
}

/* 802DBAC8-802DBB20       .text loadMtxIndx_PNCPU__11J3DShapeMtxCFiUs */
void J3DShapeMtx::loadMtxIndx_PNCPU(int mtxNo, u16 index) const {
    J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
    J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
}

/* 802DBB20-802DBB94       .text loadMtxImm_PNGP__14J3DShapeMtxImmCFiUs */
void J3DShapeMtxImm::loadMtxImm_PNGP(int mtxNo, u16 index) const {
    J3DFifoLoadPosMtxImm(j3dSys.getModelDrawMtx(index), mtxNo * 3);
    loadNrmMtx(mtxNo, index);
}

/* 802DBB94-802DBC00       .text loadMtxImm_PCPU__14J3DShapeMtxImmCFiUs */
void J3DShapeMtxImm::loadMtxImm_PCPU(int mtxNo, u16 index) const {
    J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
    loadNrmMtx(mtxNo, index);
}

/* 802DBC00-802DBC60       .text loadMtxImm_NCPU__14J3DShapeMtxImmCFiUs */
void J3DShapeMtxImm::loadMtxImm_NCPU(int mtxNo, u16 index) const {
    J3DFifoLoadPosMtxImm(j3dSys.getModelDrawMtx(index), mtxNo * 3);
    J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
}

/* 802DBC60-802DBCB8       .text loadMtxImm_PNCPU__14J3DShapeMtxImmCFiUs */
void J3DShapeMtxImm::loadMtxImm_PNCPU(int mtxNo, u16 index) const {
    J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
    J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
}

/* 802DBCB8-802DBD44       .text loadMtxConcatView_PNGP__21J3DShapeMtxConcatViewCFiUs */
void J3DShapeMtxConcatView::loadMtxConcatView_PNGP(int mtxNo, u16 index) const {
    Mtx mtx;
    MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(index), mtx);
    J3DFifoLoadPosMtxImm(mtx, mtxNo * 3);
    loadNrmMtx(mtxNo, index, mtx);
}

/* 802DBD44-802DBDD4       .text loadMtxConcatView_PCPU__21J3DShapeMtxConcatViewCFiUs */
void J3DShapeMtxConcatView::loadMtxConcatView_PCPU(int mtxNo, u16 index) const {
    Mtx mtx;
    MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(index), mtx);
    J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
    loadNrmMtx(mtxNo, index, mtx);
}

/* 802DBDD4-802DBE4C       .text loadMtxConcatView_NCPU__21J3DShapeMtxConcatViewCFiUs */
void J3DShapeMtxConcatView::loadMtxConcatView_NCPU(int mtxNo, u16 index) const {
    Mtx mtx;
    MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(index), mtx);
    J3DFifoLoadPosMtxImm(mtx, mtxNo * 3);
    J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
}

/* 802DBE4C-802DBEA4       .text loadMtxConcatView_PNCPU__21J3DShapeMtxConcatViewCFiUs */
void J3DShapeMtxConcatView::loadMtxConcatView_PNCPU(int mtxNo, u16 index) const {
    J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
    J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), mtxNo * 3);
}

J3DShapeMtx::MtxLoadIndx J3DShapeMtx::sMtxLoadPipeline[] = {
    &J3DShapeMtx::loadMtxIndx_PNGP,
    &J3DShapeMtx::loadMtxIndx_PCPU,
    &J3DShapeMtx::loadMtxIndx_NCPU,
    &J3DShapeMtx::loadMtxIndx_PNCPU,
};

/* 802DBEA4-802DBF00       .text load__11J3DShapeMtxCFv */
void J3DShapeMtx::load() const {
    MtxLoadIndx f = sMtxLoadPipeline[sCurrentPipeline];
    (this->*f)(0, mUseMtxIndex);
}

/* 802DBF00-802DBF60       .text calcNBTScale__11J3DShapeMtxFRC3VecPA3_A3_fPA3_A3_f */
void J3DShapeMtx::calcNBTScale(const Vec& scale, Mtx33* pSrc, Mtx33* pDst) {
    J3DPSMtx33Copy(pSrc[mUseMtxIndex], pDst[mUseMtxIndex]);
    J3DScaleNrmMtx33(pDst[mUseMtxIndex], scale);
}

J3DShapeMtxImm::MtxLoadImm J3DShapeMtxImm::sMtxLoadPipeline[] = {
    &J3DShapeMtxImm::loadMtxImm_PNGP,
    &J3DShapeMtxImm::loadMtxImm_PCPU,
    &J3DShapeMtxImm::loadMtxImm_NCPU,
    &J3DShapeMtxImm::loadMtxImm_PNCPU,
};

/* 802DBF60-802DBFBC       .text load__14J3DShapeMtxImmCFv */
void J3DShapeMtxImm::load() const {
    MtxLoadImm f = sMtxLoadPipeline[sCurrentPipeline];
    (this->*f)(0, mUseMtxIndex);
}

J3DShapeMtxConcatView::MtxLoadConcatView J3DShapeMtxConcatView::sMtxLoadPipeline[] = {
    &J3DShapeMtxConcatView::loadMtxConcatView_PNGP,
    &J3DShapeMtxConcatView::loadMtxConcatView_PCPU,
    &J3DShapeMtxConcatView::loadMtxConcatView_NCPU,
    &J3DShapeMtxConcatView::loadMtxConcatView_PNCPU,
};

u8* J3DShapeMtx::sCurrentScaleFlag;
u8 J3DShapeMtx::sNBTFlag;
Mtx * J3DShapeMtxConcatView::sMtxPtrTbl[2];

/* 802DBFBC-802DC08C       .text load__21J3DShapeMtxConcatViewCFv */
void J3DShapeMtxConcatView::load() const {
    sMtxPtrTbl[0] = j3dSys.getModel()->mpNodeMtx;
    sMtxPtrTbl[1] = j3dSys.getModel()->mpWeightEnvMtx;

    MtxLoadConcatView f = sMtxLoadPipeline[sCurrentPipeline];
    j3dSys.setModelDrawMtx(sMtxPtrTbl[j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex)]);
    (this->*f)(0, j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex));
}

/* 802DC08C-802DC184       .text loadNrmMtx__14J3DShapeMtxImmCFiUs */
void J3DShapeMtxImm::loadNrmMtx(int mtxNo, u16 index) const {
    if (J3DShapeMtx::sCurrentScaleFlag[index] == 1) {
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm(j3dSys.getModelDrawMtx(index), 0);
        } else {
            Mtx33 mtx33;
            Vec* scale = j3dSys.getNBTScale();
            J3DPSMtx33CopyFrom34(j3dSys.getModelDrawMtx(index), mtx33);
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    } else {
        Mtx33 mtx33;
        J3DPSCalcInverseTranspose(j3dSys.getModelDrawMtx(index), mtx33);

        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    }
}

/* 802DC184-802DC254       .text loadNrmMtx__21J3DShapeMtxConcatViewCFiUsPA4_f */
void J3DShapeMtxConcatView::loadNrmMtx(int mtxNo, u16 index, Mtx mtx) const {
    if (J3DShapeMtx::sCurrentScaleFlag[index] == 1) {
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm(mtx, 0);
        } else {
            Mtx33 mtx33;
            Vec* scale = j3dSys.getNBTScale();
            J3DPSMtx33CopyFrom34(mtx, mtx33);
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    } else {
        Mtx33 mtx33;
        J3DPSCalcInverseTranspose(mtx, mtx33);
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    }
}

/* 802DC254-802DC2F4       .text load__16J3DShapeMtxMultiCFv */
void J3DShapeMtxMulti::load() const {
    MtxLoadIndx f = sMtxLoadPipeline[sCurrentPipeline];

    for (s32 i = 0; i < mUseMtxNum; i++) {
        if (mUseMtxIndexTable[i] != 0xFFFF) {
            (this->*f)(i, mUseMtxIndexTable[i]);
        }
    }
}

/* 802DC2F4-802DC388       .text calcNBTScale__16J3DShapeMtxMultiFRC3VecPA3_A3_fPA3_A3_f */
void J3DShapeMtxMulti::calcNBTScale(const Vec& param_0, Mtx33* param_1, Mtx33* param_2) {
    for (int i = 0; i < mUseMtxNum; i++) {
        if (mUseMtxIndexTable[i] != 0xFFFF) {
            J3DPSMtx33Copy(param_1[mUseMtxIndexTable[i]], param_2[mUseMtxIndexTable[i]]);
            J3DScaleNrmMtx33(param_2[mUseMtxIndexTable[i]], param_0);
        }
    }
}

/* 802DC388-802DC428       .text load__19J3DShapeMtxMultiImmCFv */
void J3DShapeMtxMultiImm::load() const {
    MtxLoadImm f = sMtxLoadPipeline[sCurrentPipeline];

    for (s32 i = 0; i < mUseMtxNum; i++) {
        if (mUseMtxIndexTable[i] != 0xFFFF) {
            (this->*f)(i, mUseMtxIndexTable[i]);
        }
    }
}

/* 802DC428-802DC524       .text load__26J3DShapeMtxMultiConcatViewCFv */
void J3DShapeMtxMultiConcatView::load() const {
    sMtxPtrTbl[0] = j3dSys.getModel()->mpNodeMtx;
    sMtxPtrTbl[1] = j3dSys.getModel()->mpWeightEnvMtx;

    MtxLoadConcatView f = sMtxLoadPipeline[sCurrentPipeline];

    for (s32 i = 0; i < mUseMtxNum; i++) {
        u16 useMtxIndex = mUseMtxIndexTable[i];
        if (useMtxIndex != 0xFFFF) {
            u16 drawMtxIndex = j3dSys.getModel()->getModelData()->getDrawMtxIndex(useMtxIndex);
            j3dSys.setModelDrawMtx(sMtxPtrTbl[j3dSys.getModel()->getModelData()->getDrawMtxFlag(useMtxIndex)]);
            (this->*f)(i, drawMtxIndex);
        }
    }
}

/* 802DC524-802DC620       .text loadNrmMtx__19J3DShapeMtxMultiImmCFiUs */
void J3DShapeMtxMultiImm::loadNrmMtx(int mtxNo, u16 index) const {
    if (J3DShapeMtx::sCurrentScaleFlag[index] == 1) {
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm(j3dSys.getModelDrawMtx(index), mtxNo * 3);
        } else {
            Mtx33 mtx33;
            Vec* scale = j3dSys.getNBTScale();
            J3DPSMtx33CopyFrom34(j3dSys.getModelDrawMtx(index), mtx33);
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    } else {
        Mtx33 mtx33;
        J3DPSCalcInverseTranspose(j3dSys.getModelDrawMtx(index), mtx33);

        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm3x3(mtx33, mtxNo * 3);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, mtxNo * 3);
        }
    }
}

/* 802DC620-802DC6F4       .text loadNrmMtx__26J3DShapeMtxMultiConcatViewCFiUsPA4_f */
void J3DShapeMtxMultiConcatView::loadNrmMtx(int mtxNo, u16 index, Mtx mtx) const {
    if (J3DShapeMtx::sCurrentScaleFlag[index] == 1) {
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm(mtx, mtxNo * 3);
        } else {
            Mtx33 mtx33;
            Vec* scale = j3dSys.getNBTScale();
            J3DPSMtx33CopyFrom34(mtx, mtx33);
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    } else {
        Mtx33 mtx33;
        J3DPSCalcInverseTranspose(mtx, mtx33);

        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm3x3(mtx33, mtxNo * 3);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, mtxNo * 3);
        }
    }
    /* Nonmatching */
}

/* 802DC6F4-802DC7B8       .text load__20J3DShapeMtxBBoardImmCFv */
void J3DShapeMtxBBoardImm::load() const {
    Mtx mtx;
    MTXCopy(j3dSys.getModelDrawMtx(mUseMtxIndex), mtx);
    J3DCalcBBoardMtx(mtx);
    J3DFifoLoadPosMtxImm(mtx, 0);

    mtx[0][0] = 1.0f / mtx[0][0];
    mtx[1][1] = 1.0f / mtx[1][1];
    mtx[2][2] = 1.0f / mtx[2][2];
    mtx[0][3] = 0.0f;
    mtx[1][3] = 0.0f;
    mtx[2][3] = 0.0f;

    if (sNBTFlag == 0) {
        J3DFifoLoadNrmMtxImm(mtx, 0);
    } else {
        Vec* scale = j3dSys.getNBTScale();
        J3DScaleNrmMtx(mtx, *scale);
        J3DFifoLoadNrmMtxImm(mtx, 0);
    }
}

/* 802DC7B8-802DC8C0       .text load__27J3DShapeMtxBBoardConcatViewCFv */
void J3DShapeMtxBBoardConcatView::load() const {
    u16 drawMtxIndex = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex);

    Mtx mtx;
    if (j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex) == 0) {
        MtxP anmMtx = j3dSys.getModel()->getAnmMtx(drawMtxIndex);
        MTXConcat(j3dSys.getViewMtx(), anmMtx, mtx);
    } else {
        MtxP weightMtx = j3dSys.getModel()->getWeightAnmMtx(drawMtxIndex);
        MTXConcat(j3dSys.getViewMtx(), weightMtx, mtx);
    }

    J3DCalcBBoardMtx(mtx);
    J3DFifoLoadPosMtxImm(mtx, 0);

    mtx[0][0] = 1.0f / mtx[0][0];
    mtx[1][1] = 1.0f / mtx[1][1];
    mtx[2][2] = 1.0f / mtx[2][2];
    mtx[0][3] = 0.0f;
    mtx[1][3] = 0.0f;
    mtx[2][3] = 0.0f;

    if (sNBTFlag == 0) {
        J3DFifoLoadNrmMtxImm(mtx, 0);
    } else {
        Vec* scale = j3dSys.getNBTScale();
        J3DScaleNrmMtx(mtx, *scale);
        J3DFifoLoadNrmMtxImm(mtx, 0);
    }
}

/* 802DC8C0-802DC9B8       .text load__21J3DShapeMtxYBBoardImmCFv */
void J3DShapeMtxYBBoardImm::load() const {
    Mtx mtx;
    MTXCopy(j3dSys.getModelDrawMtx(mUseMtxIndex), mtx);
    J3DCalcYBBoardMtx(mtx);
    J3DFifoLoadPosMtxImm(mtx, 0);
    if (J3DShapeMtx::sCurrentScaleFlag[mUseMtxIndex] == 1) {
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm(mtx, 0);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx(mtx, *scale);
            J3DFifoLoadNrmMtxImm(mtx, 0);
        }
    } else {
        Mtx33 mtx33;
        J3DPSCalcInverseTranspose(mtx, mtx33);
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    }
    /* Nonmatching */
}

/* 802DC9B8-802DCAEC       .text load__28J3DShapeMtxYBBoardConcatViewCFv */
void J3DShapeMtxYBBoardConcatView::load() const {
    u16 drawMtxIndex = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex);

    Mtx mtx;
    if (j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex) == 0) {
        MtxP anmMtx = j3dSys.getModel()->getAnmMtx(drawMtxIndex);
        MTXConcat(j3dSys.getViewMtx(), anmMtx, mtx);
    } else {
        MtxP weightMtx = j3dSys.getModel()->getWeightAnmMtx(drawMtxIndex);
        MTXConcat(j3dSys.getViewMtx(), weightMtx, mtx);
    }
    J3DCalcYBBoardMtx(mtx);
    J3DFifoLoadPosMtxImm(mtx, 0);
    if (J3DShapeMtx::sCurrentScaleFlag[mUseMtxIndex] == 1) {
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm(mtx, 0);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx(mtx, *scale);
            J3DFifoLoadNrmMtxImm(mtx, 0);
        }
    } else {
        Mtx33 mtx33;
        J3DPSCalcInverseTranspose(mtx, mtx33);
        if (J3DShapeMtx::sNBTFlag == 0) {
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        } else {
            Vec* scale = j3dSys.getNBTScale();
            J3DScaleNrmMtx33(mtx33, *scale);
            J3DFifoLoadNrmMtxImm3x3(mtx33, 0);
        }
    }

    /* Nonmatching */
}

/* 802DCAEC-802DCB04       .text __ct__12J3DShapeDrawFPCUcUl */
J3DShapeDraw::J3DShapeDraw(const u8* pDL, u32 size) {
    mDisplayList = (void*) pDL;
    mDisplayListSize = size;
}

/* 802DCB04-802DCB30       .text draw__12J3DShapeDrawCFv */
void J3DShapeDraw::draw() const {
    GXCallDisplayList(mDisplayList, mDisplayListSize);
}
