mirror of https://github.com/zeldaret/tp.git
520 lines
17 KiB
C++
520 lines
17 KiB
C++
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
|
|
|
#include "JSystem/J3DGraphAnimator/J3DMtxBuffer.h"
|
|
#include "JSystem/J3DGraphBase/J3DMaterial.h"
|
|
#include "JSystem/J3DGraphLoader/J3DModelLoader.h"
|
|
#include "JSystem/JKernel/JKRHeap.h"
|
|
|
|
Mtx J3DMtxBuffer::sNoUseDrawMtx;
|
|
|
|
Mtx33 J3DMtxBuffer::sNoUseNrmMtx;
|
|
|
|
Mtx* J3DMtxBuffer::sNoUseDrawMtxPtr = &J3DMtxBuffer::sNoUseDrawMtx;
|
|
|
|
Mtx33* J3DMtxBuffer::sNoUseNrmMtxPtr = &J3DMtxBuffer::sNoUseNrmMtx;
|
|
|
|
// force .sdata2 order
|
|
f32 dummy1() {
|
|
return 1.0f;
|
|
}
|
|
|
|
f32 dummy0() {
|
|
return 0.0f;
|
|
}
|
|
|
|
void J3DMtxBuffer::initialize() {
|
|
mJointTree = NULL;
|
|
mpScaleFlagArr = NULL;
|
|
mpEvlpScaleFlagArr = NULL;
|
|
mpAnmMtx = NULL;
|
|
mpWeightEvlpMtx = NULL;
|
|
mpDrawMtxArr[0] = NULL;
|
|
mpDrawMtxArr[1] = NULL;
|
|
mpNrmMtxArr[0] = NULL;
|
|
mpNrmMtxArr[1] = NULL;
|
|
mpBumpMtxArr[0] = NULL;
|
|
mpBumpMtxArr[1] = NULL;
|
|
mMtxNum = 1;
|
|
mCurrentViewNo = 0;
|
|
mpUserAnmMtx = NULL;
|
|
}
|
|
|
|
enum {
|
|
J3DMdlDataFlag_ConcatView = 0x10,
|
|
J3DMdlDataFlag_NoAnimation = 0x100,
|
|
};
|
|
|
|
s32 J3DMtxBuffer::create(J3DModelData* pModelData, u32 mtxNum) {
|
|
J3D_ASSERT_NULLPTR(76, pModelData != NULL);
|
|
J3D_ASSERT_NONZEROARG(77, mtxNum != 0);
|
|
|
|
s32 ret = kJ3DError_Success;
|
|
mMtxNum = mtxNum;
|
|
mJointTree = &pModelData->getJointTree();
|
|
|
|
ret = createAnmMtx(pModelData);
|
|
if (ret != kJ3DError_Success)
|
|
return ret;
|
|
|
|
ret = createWeightEnvelopeMtx(pModelData);
|
|
if (ret != kJ3DError_Success)
|
|
return ret;
|
|
|
|
if (pModelData->checkFlag(J3DMdlDataFlag_NoAnimation)) {
|
|
setNoUseDrawMtx();
|
|
} else {
|
|
u32 loadType = getMdlDataFlag_MtxLoadType(pModelData->getFlag());
|
|
switch (loadType) {
|
|
case J3DMdlDataFlag_ConcatView:
|
|
ret = setNoUseDrawMtx();
|
|
break;
|
|
case 0:
|
|
default:
|
|
ret = createDoubleDrawMtx(pModelData, mtxNum);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ret != kJ3DError_Success)
|
|
return ret;
|
|
|
|
if (pModelData->getFlag() & J3DMdlDataFlag_ConcatView) {
|
|
pModelData->setBumpFlag(0);
|
|
} else {
|
|
ret = createBumpMtxArray(pModelData, mtxNum);
|
|
|
|
if (ret != kJ3DError_Success)
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
J3DError J3DMtxBuffer::createAnmMtx(J3DModelData* pModelData) {
|
|
if (pModelData->getJointNum() != 0) {
|
|
mpScaleFlagArr = new u8[pModelData->getJointNum()];
|
|
mpAnmMtx = new Mtx[pModelData->getJointNum()];
|
|
mpUserAnmMtx = mpAnmMtx;
|
|
}
|
|
|
|
if (mpScaleFlagArr == NULL)
|
|
return kJ3DError_Alloc;
|
|
|
|
if (mpAnmMtx == NULL) {
|
|
return kJ3DError_Alloc;
|
|
}
|
|
|
|
return kJ3DError_Success;
|
|
}
|
|
|
|
s32 J3DMtxBuffer::createWeightEnvelopeMtx(J3DModelData* pModelData) {
|
|
if (pModelData->getWEvlpMtxNum() != 0) {
|
|
mpEvlpScaleFlagArr = new u8[pModelData->getWEvlpMtxNum()];
|
|
mpWeightEvlpMtx = new Mtx[pModelData->getWEvlpMtxNum()];
|
|
}
|
|
|
|
if (pModelData->getWEvlpMtxNum() != 0 && mpEvlpScaleFlagArr == NULL)
|
|
return kJ3DError_Alloc;
|
|
if (pModelData->getWEvlpMtxNum() != 0 && mpWeightEvlpMtx == NULL)
|
|
return kJ3DError_Alloc;
|
|
|
|
return kJ3DError_Success;
|
|
}
|
|
|
|
s32 J3DMtxBuffer::setNoUseDrawMtx() {
|
|
mpDrawMtxArr[0] = mpDrawMtxArr[1] = &sNoUseDrawMtxPtr;
|
|
mpNrmMtxArr[0] = mpNrmMtxArr[1] = &sNoUseNrmMtxPtr;
|
|
mpBumpMtxArr[0] = mpBumpMtxArr[1] = NULL;
|
|
return kJ3DError_Success;
|
|
}
|
|
|
|
s32 J3DMtxBuffer::createDoubleDrawMtx(J3DModelData* pModelData, u32 mtxNum) {
|
|
if (mtxNum != 0) {
|
|
for (s32 i = 0; i < 2; i++) {
|
|
mpDrawMtxArr[i] = new Mtx*[mtxNum];
|
|
mpNrmMtxArr[i] = new Mtx33*[mtxNum];
|
|
mpBumpMtxArr[i] = NULL;
|
|
}
|
|
}
|
|
|
|
if (mtxNum != 0) {
|
|
for (s32 i = 0; i < 2; i++) {
|
|
if (mpDrawMtxArr[i] == NULL)
|
|
return kJ3DError_Alloc;
|
|
if (mpNrmMtxArr[i] == NULL)
|
|
return kJ3DError_Alloc;
|
|
}
|
|
}
|
|
|
|
for (s32 i = 0; i < 2; i++) {
|
|
for (u32 j = 0; j < mtxNum; j++) {
|
|
if (pModelData->getDrawMtxNum() != 0) {
|
|
mpDrawMtxArr[i][j] = new (0x20) Mtx[pModelData->getDrawMtxNum()];
|
|
mpNrmMtxArr[i][j] = new (0x20) Mtx33[pModelData->getDrawMtxNum()];
|
|
}
|
|
}
|
|
}
|
|
|
|
for (s32 i = 0; i < 2; i++) {
|
|
for (u32 j = 0; j < mtxNum; j++) {
|
|
if (pModelData->getDrawMtxNum() != 0) {
|
|
if (mpDrawMtxArr[i][j] == NULL)
|
|
return kJ3DError_Alloc;
|
|
if (mpNrmMtxArr[i][j] == NULL)
|
|
return kJ3DError_Alloc;
|
|
}
|
|
}
|
|
}
|
|
|
|
return kJ3DError_Success;
|
|
}
|
|
|
|
s32 J3DMtxBuffer::createBumpMtxArray(J3DModelData* i_modelData, u32 mtxNum) {
|
|
J3D_ASSERT_NULLPTR(295, i_modelData != NULL);
|
|
|
|
if (i_modelData->getModelDataType() == 0) {
|
|
u16 bumpMtxNum = 0;
|
|
u16 materialCount = 0;
|
|
u16 materialNum = i_modelData->getMaterialNum();
|
|
for (u16 j = 0; j < materialNum; j++) {
|
|
J3DMaterial* material = i_modelData->getMaterialNodePointer(j);
|
|
if (material->getNBTScale()->mbHasScale == true) {
|
|
bumpMtxNum += material->getShape()->countBumpMtxNum();
|
|
materialCount++;
|
|
}
|
|
}
|
|
|
|
if (bumpMtxNum != 0 && mtxNum != 0) {
|
|
for (int i = 0; i < 2; i++) {
|
|
mpBumpMtxArr[i] = new Mtx33**[(u16)materialCount];
|
|
if (mpBumpMtxArr[i] == NULL) {
|
|
return kJ3DError_Alloc;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
u32 offset = 0;
|
|
u16 materialNum = i_modelData->getMaterialNum();
|
|
for (u16 j = 0; j < materialNum; j++) {
|
|
J3DMaterial* material = i_modelData->getMaterialNodePointer(j);
|
|
if (material->getNBTScale()->mbHasScale == true) {
|
|
mpBumpMtxArr[i][offset] = new Mtx33*[mtxNum];
|
|
if (mpBumpMtxArr[i][offset] == NULL) {
|
|
return kJ3DError_Alloc;
|
|
}
|
|
material->getShape()->setBumpMtxOffset(offset);
|
|
offset++;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
u32 offset = 0;
|
|
u16 materialNum = i_modelData->getMaterialNum();
|
|
for (u16 j = 0; j < materialNum; j++) {
|
|
J3DMaterial* material = i_modelData->getMaterialNodePointer((u16)j);
|
|
if (material->getNBTScale()->mbHasScale == true) {
|
|
for (int k = 0; k < mtxNum; k++) {
|
|
mpBumpMtxArr[i][offset][k] = new (0x20) Mtx33[i_modelData->getDrawMtxNum()];
|
|
if (mpBumpMtxArr[i][offset][k] == NULL) {
|
|
return kJ3DError_Alloc;
|
|
}
|
|
}
|
|
offset++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (materialCount != 0) {
|
|
i_modelData->setBumpFlag(1);
|
|
}
|
|
}
|
|
|
|
return kJ3DError_Success;
|
|
}
|
|
|
|
static f32 J3DUnit01[] = { 0.0f, 1.0f };
|
|
|
|
void J3DMtxBuffer::calcWeightEnvelopeMtx() {
|
|
register MtxP weightAnmMtx;
|
|
register Mtx* worldMtx;
|
|
register Mtx* invMtx;
|
|
register f32 weight;
|
|
int idx;
|
|
int j;
|
|
int mixNum;
|
|
int i;
|
|
int max;
|
|
u16* indices;
|
|
f32* weights;
|
|
u8* pScale;
|
|
|
|
#if DEBUG || !__MWERKS__
|
|
register Mtx mtx;
|
|
#else
|
|
register f32 var_f1;
|
|
register f32 var_f2;
|
|
register f32 var_f3;
|
|
register f32 var_f4;
|
|
register f32 var_f5;
|
|
register f32 var_f6;
|
|
register f32 var_f7;
|
|
register f32 var_f8;
|
|
register f32 var_f9;
|
|
register f32 var_f10;
|
|
register f32 var_f11;
|
|
register f32 var_f12;
|
|
register f32 var_f13;
|
|
register f32 var_f31;
|
|
register f32 var_f30;
|
|
register f32 var_f29;
|
|
register f32 var_f28;
|
|
register f32 var_f27;
|
|
register f32* var_r7 = J3DUnit01;
|
|
#endif
|
|
|
|
i = -1;
|
|
max = mJointTree->getWEvlpMtxNum();
|
|
indices = mJointTree->getWEvlpMixMtxIndex() - 1;
|
|
weights = mJointTree->getWEvlpMixWeight() - 1;
|
|
|
|
#if !DEBUG && __MWERKS__
|
|
asm {
|
|
psq_l var_f27, 0x0(var_r7), 0, 0 /* qr0 */
|
|
ps_merge00 var_f10, var_f27, var_f27
|
|
ps_merge00 var_f12, var_f27, var_f27
|
|
ps_merge00 var_f31, var_f27, var_f27
|
|
}
|
|
#endif
|
|
|
|
while (++i < max) {
|
|
pScale = &mpEvlpScaleFlagArr[i];
|
|
*pScale = 1;
|
|
weightAnmMtx = mpWeightEvlpMtx[i];
|
|
|
|
#if DEBUG || !__MWERKS__
|
|
weightAnmMtx[0][0] = weightAnmMtx[0][1] = weightAnmMtx[0][2] = weightAnmMtx[0][3] =
|
|
weightAnmMtx[1][0] = weightAnmMtx[1][1] = weightAnmMtx[1][2] = weightAnmMtx[1][3] =
|
|
weightAnmMtx[2][0] = weightAnmMtx[2][1] = weightAnmMtx[2][2] = weightAnmMtx[2][3] = 0.0f;
|
|
#else
|
|
asm {
|
|
ps_merge00 var_f9, var_f27, var_f27
|
|
ps_merge00 var_f11, var_f27, var_f27
|
|
ps_merge00 var_f13, var_f27, var_f27
|
|
}
|
|
#endif
|
|
|
|
j = 0;
|
|
mixNum = mJointTree->getWEvlpMixMtxNum(i);
|
|
do {
|
|
idx = *++indices;
|
|
worldMtx = &mpAnmMtx[idx];
|
|
invMtx = &mJointTree->getInvJointMtx((u16)idx);
|
|
|
|
#if DEBUG || !__MWERKS__
|
|
MTXConcat(*worldMtx, *invMtx, mtx);
|
|
#else
|
|
// Fakematch? Doesn't match if worldMtx and invMtx are used directly.
|
|
register void* var_r5 = worldMtx;
|
|
register void* var_r6 = invMtx;
|
|
asm {
|
|
psq_l var_f2, 0x0(var_r6), 0, 0 /* qr0 */
|
|
psq_l var_f1, 0x0(var_r5), 0, 0 /* qr0 */
|
|
psq_l var_f3, 0x10(var_r5), 0, 0 /* qr0 */
|
|
psq_l var_f5, 0x20(var_r5), 0, 0 /* qr0 */
|
|
ps_muls0 var_f8, var_f2, var_f1
|
|
psq_l var_f6, 0x10(var_r6), 0, 0 /* qr0 */
|
|
ps_muls0 var_f30, var_f2, var_f3
|
|
ps_muls0 var_f29, var_f2, var_f5
|
|
psq_l var_f7, 0x20(var_r6), 0, 0 /* qr0 */
|
|
ps_madds1 var_f8, var_f6, var_f1, var_f8
|
|
psq_l var_f2, 0x8(var_r5), 0, 0 /* qr0 */
|
|
ps_madds1 var_f30, var_f6, var_f3, var_f30
|
|
psq_l var_f4, 0x18(var_r5), 0, 0 /* qr0 */
|
|
ps_madds1 var_f29, var_f6, var_f5, var_f29
|
|
psq_l var_f6, 0x28(var_r5), 0, 0 /* qr0 */
|
|
ps_madds0 var_f8, var_f7, var_f2, var_f8
|
|
}
|
|
#endif
|
|
|
|
weight = *++weights;
|
|
|
|
#if DEBUG || !__MWERKS__
|
|
weightAnmMtx[0][0] += mtx[0][0] * weight;
|
|
weightAnmMtx[0][1] += mtx[0][1] * weight;
|
|
weightAnmMtx[0][2] += mtx[0][2] * weight;
|
|
weightAnmMtx[0][3] += mtx[0][3] * weight;
|
|
weightAnmMtx[1][0] += mtx[1][0] * weight;
|
|
weightAnmMtx[1][1] += mtx[1][1] * weight;
|
|
weightAnmMtx[1][2] += mtx[1][2] * weight;
|
|
weightAnmMtx[1][3] += mtx[1][3] * weight;
|
|
weightAnmMtx[2][0] += mtx[2][0] * weight;
|
|
weightAnmMtx[2][1] += mtx[2][1] * weight;
|
|
weightAnmMtx[2][2] += mtx[2][2] * weight;
|
|
weightAnmMtx[2][3] += mtx[2][3] * weight;
|
|
#else
|
|
asm {
|
|
ps_madds0 var_f30, var_f7, var_f4, var_f30
|
|
ps_madds0 var_f29, var_f7, var_f6, var_f29
|
|
psq_l var_f7, 0x8(var_r6), 0, 0 /* qr0 */
|
|
ps_madds0 var_f9, var_f8, weight, var_f9
|
|
ps_madds0 var_f11, var_f30, weight, var_f11
|
|
ps_madds0 var_f13, var_f29, weight, var_f13
|
|
psq_l var_f8, 0x18(var_r6), 0, 0 /* qr0 */
|
|
ps_muls0 var_f30, var_f7, var_f1
|
|
ps_muls0 var_f29, var_f7, var_f3
|
|
ps_muls0 var_f28, var_f7, var_f5
|
|
psq_l var_f7, 0x28(var_r6), 0, 0 /* qr0 */
|
|
psq_st var_f9, 0x0(weightAnmMtx), 0, 0 /* qr0 */
|
|
ps_madds1 var_f30, var_f8, var_f1, var_f30
|
|
ps_madds1 var_f29, var_f8, var_f3, var_f29
|
|
ps_madds1 var_f28, var_f8, var_f5, var_f28
|
|
ps_madds0 var_f30, var_f7, var_f2, var_f30
|
|
ps_madds0 var_f29, var_f7, var_f4, var_f29
|
|
ps_madds0 var_f28, var_f7, var_f6, var_f28
|
|
psq_st var_f11, 0x10(weightAnmMtx), 0, 0 /* qr0 */
|
|
psq_st var_f13, 0x20(weightAnmMtx), 0, 0 /* qr0 */
|
|
ps_madd var_f30, var_f27, var_f2, var_f30
|
|
ps_madd var_f29, var_f27, var_f4, var_f29
|
|
ps_madd var_f28, var_f27, var_f6, var_f28
|
|
ps_madds0 var_f10, var_f30, weight, var_f10
|
|
ps_madds0 var_f12, var_f29, weight, var_f12
|
|
ps_madds0 var_f31, var_f28, weight, var_f31
|
|
}
|
|
#endif
|
|
|
|
*pScale &= mpScaleFlagArr[idx];
|
|
} while (++j < mixNum);
|
|
|
|
#if !DEBUG && __MWERKS__
|
|
asm {
|
|
psq_st var_f10, 0x8(weightAnmMtx), 0, 0 /* qr0 */
|
|
ps_merge00 var_f10, var_f27, var_f27
|
|
psq_st var_f12, 0x18(weightAnmMtx), 0, 0 /* qr0 */
|
|
ps_merge00 var_f12, var_f27, var_f27
|
|
psq_st var_f31, 0x28(weightAnmMtx), 0, 0 /* qr0 */
|
|
ps_merge00 var_f31, var_f27, var_f27
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void J3DMtxBuffer::calcDrawMtx(u32 mdlFlag, Vec const& param_1, Mtx const& param_2) {
|
|
Mtx* sp24, *sp20;
|
|
int sp1C = 0;
|
|
sp20 = mpAnmMtx;
|
|
sp24 = mpWeightEvlpMtx;
|
|
|
|
MtxP viewMtx;
|
|
Mtx viewBaseMtx;
|
|
u16 fullWgtNum;
|
|
|
|
switch (mdlFlag) {
|
|
case 0:
|
|
viewMtx = j3dSys.getViewMtx();
|
|
fullWgtNum = mJointTree->getDrawFullWgtMtxNum();
|
|
for (u16 i = 0; i < fullWgtNum; i++) {
|
|
MTXConcat(viewMtx, getAnmMtx(mJointTree->getDrawMtxIndex(i)), *getDrawMtx(i));
|
|
}
|
|
if (mJointTree->getDrawMtxNum() > fullWgtNum) {
|
|
J3DPSMtxArrayConcat(viewMtx, *mpWeightEvlpMtx, *getDrawMtx(fullWgtNum),
|
|
mJointTree->getWEvlpMtxNum());
|
|
}
|
|
return;
|
|
case 1:
|
|
fullWgtNum = mJointTree->getDrawFullWgtMtxNum();
|
|
for (u16 i = 0; i < fullWgtNum; i++) {
|
|
MTXCopy(getAnmMtx(mJointTree->getDrawMtxIndex(i)), *getDrawMtx(i));
|
|
}
|
|
fullWgtNum = mJointTree->getDrawFullWgtMtxNum();
|
|
for (u16 i = 0; i < fullWgtNum; i++) {
|
|
MTXCopy(getWeightAnmMtx(i), *getDrawMtx(mJointTree->getDrawFullWgtMtxNum() + i));
|
|
}
|
|
break;
|
|
case 2:
|
|
J3DCalcViewBaseMtx(j3dSys.getViewMtx(), param_1, param_2, viewBaseMtx);
|
|
fullWgtNum = mJointTree->getDrawFullWgtMtxNum();
|
|
for (u16 i = 0; i < fullWgtNum; i++) {
|
|
MTXConcat(viewBaseMtx, getAnmMtx(mJointTree->getDrawMtxIndex(i)), *getDrawMtx(i));
|
|
}
|
|
if (mJointTree->getDrawMtxNum() > mJointTree->getDrawFullWgtMtxNum()) {
|
|
J3DPSMtxArrayConcat(viewBaseMtx, *mpWeightEvlpMtx,
|
|
*getDrawMtx(mJointTree->getDrawFullWgtMtxNum()),
|
|
mJointTree->getWEvlpMtxNum());
|
|
}
|
|
return;
|
|
default:
|
|
JUT_ASSERT_MSG(778, 0, "Error : model flag is invalid.")
|
|
}
|
|
}
|
|
|
|
void J3DMtxBuffer::calcNrmMtx() {
|
|
u16 drawMtxNum = mJointTree->getDrawMtxNum();
|
|
for (u16 i = 0; i < drawMtxNum; i++) {
|
|
if (mJointTree->getDrawMtxFlag(i) == 0) {
|
|
if (getScaleFlag(mJointTree->getDrawMtxIndex(i)) == 1) {
|
|
setNrmMtx(i, *getDrawMtx(i));
|
|
} else {
|
|
J3DPSCalcInverseTranspose(*getDrawMtx(i), *getNrmMtx(i));
|
|
}
|
|
} else {
|
|
if (getEnvScaleFlag(mJointTree->getDrawMtxIndex(i)) == 1) {
|
|
setNrmMtx(i, *getDrawMtx(i));
|
|
} else {
|
|
J3DPSCalcInverseTranspose(*getDrawMtx(i), *getNrmMtx(i));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void J3DMtxBuffer::calcBBoardMtx() {
|
|
u16 drawMtxNum = mJointTree->getDrawMtxNum();
|
|
for (u16 i = 0; i < drawMtxNum; i++) {
|
|
if (mJointTree->getDrawMtxFlag(i) == 0) {
|
|
u16 index = mJointTree->getDrawMtxIndex(i);
|
|
if (mJointTree->getJointNodePointer(index)->getMtxType() == 1) {
|
|
MtxP drawMtx = *getDrawMtx(i);
|
|
J3DCalcBBoardMtx(drawMtx);
|
|
|
|
Mtx33* nrmMtx = getNrmMtx(i);
|
|
(*nrmMtx)[0][0] = 1.0f / drawMtx[0][0];
|
|
(*nrmMtx)[0][1] = 0.0f;
|
|
(*nrmMtx)[0][2] = 0.0f;
|
|
(*nrmMtx)[1][0] = 0.0f;
|
|
(*nrmMtx)[1][1] = 1.0f / drawMtx[1][1];
|
|
(*nrmMtx)[1][2] = 0.0f;
|
|
(*nrmMtx)[2][0] = 0.0f;
|
|
(*nrmMtx)[2][1] = 0.0f;
|
|
(*nrmMtx)[2][2] = 1.0f / drawMtx[2][2];
|
|
} else if (mJointTree->getJointNodePointer(index)->getMtxType() == 2) {
|
|
MtxP drawMtx = *getDrawMtx(i);
|
|
J3DCalcYBBoardMtx(drawMtx);
|
|
Mtx33* nrmMtx = getNrmMtx(i);
|
|
J3DPSCalcInverseTranspose(drawMtx, *nrmMtx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void J3DCalcViewBaseMtx(Mtx view, Vec const& scale, const Mtx& base, Mtx dst) {
|
|
Mtx m;
|
|
|
|
m[0][0] = base[0][0] * scale.x;
|
|
m[0][1] = base[0][1] * scale.y;
|
|
m[0][2] = base[0][2] * scale.z;
|
|
m[0][3] = base[0][3];
|
|
|
|
m[1][0] = base[1][0] * scale.x;
|
|
m[1][1] = base[1][1] * scale.y;
|
|
m[1][2] = base[1][2] * scale.z;
|
|
m[1][3] = base[1][3];
|
|
|
|
m[2][0] = base[2][0] * scale.x;
|
|
m[2][1] = base[2][1] * scale.y;
|
|
m[2][2] = base[2][2] * scale.z;
|
|
m[2][3] = base[2][3];
|
|
|
|
MTXConcat(view, m, dst);
|
|
}
|