Document remaining SPLDraw functions

This commit is contained in:
Fexty12573 2024-08-02 23:07:11 +02:00
parent 8613ab46c8
commit 2538b82bf0
4 changed files with 303 additions and 344 deletions

View File

@ -22,12 +22,12 @@
void SPLDraw_Child_Billboard(SPLManager *mgr, SPLParticle *ptcl);
void SPLDraw_Child_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl);
void sub_0209E650(SPLManager *mgr, SPLParticle *ptcl);
void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl);
void SPLDraw_Child_Polygon(SPLManager *mgr, SPLParticle *ptcl);
void SPLDraw_Child_DirectionalPolygon(SPLManager *mgr, SPLParticle *ptcl);
void SPLDraw_Billboard(SPLManager *mgr, SPLParticle *ptcl);
void SPLDraw_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl);
void sub_0209E9A0(SPLManager *mgr, SPLParticle *ptcl);
void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl);
void SPLDraw_Polygon(SPLManager *mgr, SPLParticle *ptcl);
void SPLDraw_DirectionalPolygon(SPLManager *mgr, SPLParticle *ptcl);
void SPLAnim_Scale(SPLParticle *ptcl, SPLResource *res, int lifeRate); // spl_scl_in_out
void SPLAnim_Color(SPLParticle *ptcl, SPLResource *res, int lifeRate); // spl_clr_in_out

View File

@ -9,9 +9,9 @@
enum SPLCircleAxis {
SPL_CIRCLE_AXIS_Z = 0,
SPL_CIRCLE_AXIS_Y = 1,
SPL_CIRCLE_AXIS_X = 2,
SPL_CIRCLE_AXIS_EMITTER = 3, // The emitter's axis
SPL_CIRCLE_AXIS_Y,
SPL_CIRCLE_AXIS_X,
SPL_CIRCLE_AXIS_EMITTER, // The emitter's axis
};
enum SPLEmissionType {
@ -29,14 +29,19 @@ enum SPLEmissionType {
enum SPLChildRotationType {
SPL_CHILD_ROT_NONE = 0,
SPL_CHILD_ROT_INHERIT_ANGLE = 1,
SPL_CHILD_ROT_INHERIT_ANGLE_AND_VELOCITY = 2,
SPL_CHILD_ROT_INHERIT_ANGLE,
SPL_CHILD_ROT_INHERIT_ANGLE_AND_VELOCITY,
};
enum SPLScaleAnimDir {
SPL_SCALE_ANIM_DIR_XY = 0,
SPL_SCALE_ANIM_DIR_X = 1,
SPL_SCALE_ANIM_DIR_Y = 2,
SPL_SCALE_ANIM_DIR_X,
SPL_SCALE_ANIM_DIR_Y,
};
enum SPLPolygonRotAxis {
SPL_POLYGON_ROT_AXIS_Y = 0,
SPL_POLYGON_ROT_AXIS_XYZ,
};
typedef struct SPLArcHdr {
@ -69,8 +74,8 @@ typedef union SPLResourceFlags {
u32 selfMaintaining : 1;
u32 followEmitter : 1;
u32 hasChildResource : 1;
u32 unk_06_1 : 2;
u32 unk_06_3 : 1;
u32 polygonRotAxis : 2; // The axis to rotate the polygon around when using the 'polygon' draw types
u32 polygonReferencePlane : 1;
u32 randomizeLoopedAnim : 1;
u32 drawChildrenFirst : 1; // If set, child particles will be rendered before parent particles
u32 hideParent : 1; // If set, only child particles will be rendered
@ -96,8 +101,8 @@ typedef union SPLChildResourceFlags {
u16 followEmitter : 1;
u16 useChildColor : 1;
u16 drawType : 2;
u16 unk_03_1 : 2;
u16 unk_03_3 : 1;
u16 polygonRotAxis : 2;
u16 polygonReferencePlane : 1;
u16 reserved_03_4 : 4;
};
} SPLChildResourceFlags;
@ -160,7 +165,7 @@ typedef struct SPLResourceHeader {
u32 textureTileCountS : 2; // Number of times to tile the texture in the S direction
u32 textureTileCountT : 2; // Number of times to tile the texture in the T direction
u32 scaleAnimDir : 3; // Maps to SPLScaleAnimDir
u32 unk_07_7 : 1;
u32 dpolFaceEmitter : 1; // If set, the polygon will face the emitter
u32 flipTextureS : 1;
u32 flipTextureT : 1;
u32 unk_08_2 : 3;
@ -246,7 +251,7 @@ typedef struct SPLChildResource {
u32 textureTileCountT : 2;
u32 flipTextureS : 1;
u32 flipTextureT : 1;
u32 unk_04_6 : 1;
u32 dpolFaceEmitter : 1; // If set, the polygon will face the emitter
u32 reserved_04_7 : 25;
} misc;
} SPLChildResource;

View File

@ -341,13 +341,13 @@ static void SPLManager_DrawParticles(SPLManager *mgr)
drawFunc = SPLDraw_DirectionalBillboard;
break;
case 2:
drawFunc = sub_0209E9A0;
drawFunc = SPLDraw_Polygon;
break;
case 3:
drawFunc = sub_0209E1D4;
drawFunc = SPLDraw_DirectionalPolygon;
break;
case 4:
drawFunc = sub_0209E1D4;
drawFunc = SPLDraw_DirectionalPolygon;
break;
}
@ -379,13 +379,13 @@ static void SPLManager_DrawChildParticles(SPLManager *mgr)
drawFunc = SPLDraw_Child_DirectionalBillboard;
break;
case 2:
drawFunc = sub_0209E650;
drawFunc = SPLDraw_Child_Polygon;
break;
case 3:
drawFunc = sub_0209DD54;
drawFunc = SPLDraw_Child_DirectionalPolygon;
break;
case 4:
drawFunc = sub_0209DD54;
drawFunc = SPLDraw_Child_DirectionalPolygon;
break;
}

View File

@ -17,13 +17,13 @@ typedef void (*DrawPlaneFunc)(fx16 s, fx16 t, fx16 offsetX, fx16 offsetY);
void SPLDraw_Child_Billboard(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_chld_bb
void SPLDraw_Child_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_chld_dbb
void sub_0209E650(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_chld_pol
void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_chld_dpl
void SPLDraw_Child_Polygon(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_chld_pol
void SPLDraw_Child_DirectionalPolygon(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_chld_dpl
void SPLDraw_Billboard(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_bb
void SPLDraw_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_dbb
void sub_0209E9A0(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_pol
void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_dpl
void SPLDraw_Polygon(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_pol
void SPLDraw_DirectionalPolygon(SPLManager *mgr, SPLParticle *ptcl); // spl_draw_dpl
static void SPLUtil_DrawXYPlane(fx16 s, fx16 t, fx16 offsetX, fx16 offsetY);
static void SPLUtil_DrawXZPlane(fx16 s, fx16 t, fx16 offsetX, fx16 offsetZ);
@ -308,7 +308,7 @@ void SPLDraw_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl)
VecFx32 trs;
fx32 sclX, sclY;
VecFx32 dir, look;
MtxFx33 mtx;
MtxFx33 mat;
MtxFx43 load;
const MtxFx43 *cmr = mgr->renderState.viewMatrix;
@ -353,8 +353,8 @@ void SPLDraw_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl)
}
VEC_Normalize(&dir, &dir);
MTX_Copy43To33(cmr, &mtx);
MTX_MultVec33(&dir, &mtx, &dir);
MTX_Copy43To33(cmr, &mat);
MTX_MultVec33(&dir, &mat, &dir);
MTX_MultVec43(&trs, cmr, &trs);
vel_dir = ptcl->velocity;
@ -398,8 +398,8 @@ void SPLDraw_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl)
}
VEC_Normalize(&dir, &dir);
MTX_Copy43To33(cmr, &mtx);
MTX_MultVec33(&dir, &mtx, &dir);
MTX_Copy43To33(cmr, &mat);
MTX_MultVec33(&dir, &mat, &dir);
MTX_MultVec43(&trs, cmr, &trs);
vel_dir = ptcl->velocity;
@ -451,7 +451,7 @@ void SPLDraw_Child_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl)
VecFx32 trs;
fx32 sclX, sclY;
VecFx32 dir, look;
MtxFx33 mtx;
MtxFx33 mat;
MtxFx43 load;
const MtxFx43 *cmr = mgr->renderState.viewMatrix;
@ -496,8 +496,8 @@ void SPLDraw_Child_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl)
}
VEC_Normalize(&dir, &dir);
MTX_Copy43To33(cmr, &mtx);
MTX_MultVec33(&dir, &mtx, &dir);
MTX_Copy43To33(cmr, &mat);
MTX_MultVec33(&dir, &mat, &dir);
MTX_MultVec43(&trs, cmr, &trs);
vel_dir = ptcl->velocity;
@ -541,8 +541,8 @@ void SPLDraw_Child_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl)
}
VEC_Normalize(&dir, &dir);
MTX_Copy43To33(cmr, &mtx);
MTX_MultVec33(&dir, &mtx, &dir);
MTX_Copy43To33(cmr, &mat);
MTX_MultVec33(&dir, &mat, &dir);
MTX_MultVec43(&trs, cmr, &trs);
vel_dir = ptcl->velocity;
@ -583,402 +583,356 @@ void SPLDraw_Child_DirectionalBillboard(SPLManager *mgr, SPLParticle *ptcl)
SPLUtil_DrawXYPlane(mgr->renderState.emitter->childTextureS, mgr->renderState.emitter->childTextureT, 0, 0);
}
void sub_0209E9A0(SPLManager *mgr, SPLParticle *ptcl)
void SPLDraw_Polygon(SPLManager *mgr, SPLParticle *ptcl)
{
fx32 sclX, sclY;
MtxFx43 load;
MtxFx43 rotMtx;
MtxFx43 sclMtx;
u32 polygonID, cullMode;
fx32 alpha;
SPLResourceHeader *resBase;
alpha = (fx32)(ptcl->visibility.baseAlpha * (ptcl->visibility.animAlpha + 1)) >> 5;
G3_PolygonAttr(
GX_LIGHTMASK_NONE,
GX_POLYGONMODE_MODULATE,
GX_CULL_NONE,
ptcl->visibility.currentPolygonID,
alpha,
mgr->miscPolygonAttr);
reg_G3_POLYGON_ATTR;
if (alpha == 0) {
return;
}
sRotationFunctions[mgr->renderState.emitter->resource->header->flags.unk_06_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMtx);
sclY = ptcl->baseScale;
resBase = mgr->renderState.emitter->resource->header;
sclX = FX_MUL(sclY, resBase->aspectRatio);
switch (resBase->misc.scaleAnimDir) {
case 0:
sclX = FX_MUL(sclX, ptcl->animScale);
sclY = FX_MUL(sclY, ptcl->animScale);
break;
case 1:
sclX = FX_MUL(sclX, ptcl->animScale);
break;
case 2:
sclY = FX_MUL(sclY, ptcl->animScale);
break;
}
MTX_Scale43(&sclMtx, sclX, sclY, sclY);
MTX_Concat43(&sclMtx, &rotMtx, &load);
// resBase = mgr->unk_40.unk_00->p_res->header;
if (!mgr->renderState.emitter->resource->header->flags.useViewSpace) {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
G3_LoadMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
} else {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
G3_Identity();
resBase = mgr->renderState.emitter->resource->header;
G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z);
G3_MultMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
}
GXRgb colA = ptcl->color;
GXRgb colB = mgr->renderState.emitter->color;
G3_Color(GX_RGB(
GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5,
GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15,
GX_RGB_B_(colA) * GX_RGB_B_(colB) >> 25));
SPLEmitter *emtr = mgr->renderState.emitter;
resBase = emtr->resource->header;
sPlaneDrawingFunctions[resBase->flags.unk_06_3](emtr->textureS, emtr->textureT, resBase->polygonX, resBase->polygonY);
}
void sub_0209E650(SPLManager *mgr, SPLParticle *ptcl)
{
fx32 sclX, sclY;
MtxFx43 load;
MtxFx43 rotMtx;
MtxFx43 sclMtx;
u32 polygonID, cullMode;
fx32 alpha;
SPLResourceHeader *resBase;
alpha = ptcl->visibility.baseAlpha * (ptcl->visibility.animAlpha + 1) >> 5;
G3_PolygonAttr(
GX_LIGHTMASK_NONE,
GX_POLYGONMODE_MODULATE,
GX_CULL_NONE,
ptcl->visibility.currentPolygonID,
alpha,
mgr->miscPolygonAttr);
reg_G3_POLYGON_ATTR;
if (alpha == 0) {
return;
}
sRotationFunctions[mgr->renderState.emitter->resource->childResource->flags.unk_03_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMtx);
sclY = ptcl->baseScale;
resBase = mgr->renderState.emitter->resource->header;
sclX = FX_MUL(sclY, resBase->aspectRatio);
switch (resBase->misc.scaleAnimDir) {
case 0:
sclX = FX_MUL(sclX, ptcl->animScale);
sclY = FX_MUL(sclY, ptcl->animScale);
break;
case 1:
sclX = FX_MUL(sclX, ptcl->animScale);
break;
case 2:
sclY = FX_MUL(sclY, ptcl->animScale);
break;
}
MTX_Scale43(&sclMtx, sclX, sclY, sclY);
MTX_Concat43(&rotMtx, &sclMtx, &load);
if (!mgr->renderState.emitter->resource->header->flags.useViewSpace) {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
G3_LoadMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
} else {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
G3_Identity();
resBase = mgr->renderState.emitter->resource->header;
G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z);
G3_MultMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
}
GXRgb colA = ptcl->color;
GXRgb colB = mgr->renderState.emitter->color;
G3_Color(GX_RGB(
GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5,
GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15,
GX_RGB_B_(colA) * GX_RGB_B_(colB) >> 25));
SPLEmitter *emtr = mgr->renderState.emitter;
sPlaneDrawingFunctions[emtr->resource->childResource->flags.unk_03_3](emtr->childTextureS, emtr->childTextureT, 0, 0);
}
void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl)
{
MtxFx43 transform;
MtxFx43 rotMat;
MtxFx43 sclMat;
VecFx32 vec1, vec2, vec3, vec4, axis;
MtxFx43 mat;
fx32 dot, scaleX, scaleY, alpha, tmp;
SPLResourceHeader *resBase;
SPLEmitter *emtr;
GXRgb colA, colB;
u32 polygonID, cullMode;
alpha = ptcl->visibility.baseAlpha * (ptcl->visibility.animAlpha + 1) >> 5;
G3_PolygonAttr(
GX_LIGHTMASK_NONE,
GX_POLYGONMODE_MODULATE,
GX_CULL_NONE,
ptcl->visibility.currentPolygonID,
alpha,
mgr->miscPolygonAttr);
reg_G3_POLYGON_ATTR;
if (alpha == 0) {
if (SPLDraw_Setup(ptcl, mgr)) {
return;
}
sRotationFunctions[mgr->renderState.emitter->resource->header->flags.unk_06_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMat);
sRotationFunctions[mgr->renderState.emitter->resource->header->flags.polygonRotAxis](
FX_SinIdx(ptcl->rotation),
FX_CosIdx(ptcl->rotation),
&rotMat);
sclY = ptcl->baseScale;
sclX = FX_MUL(sclY, mgr->renderState.emitter->resource->header->aspectRatio);
switch (mgr->renderState.emitter->resource->header->misc.scaleAnimDir) {
case SPL_SCALE_ANIM_DIR_XY:
sclX = FX_MUL(sclX, ptcl->animScale);
sclY = FX_MUL(sclY, ptcl->animScale);
break;
case SPL_SCALE_ANIM_DIR_X:
sclX = FX_MUL(sclX, ptcl->animScale);
break;
case SPL_SCALE_ANIM_DIR_Y:
sclY = FX_MUL(sclY, ptcl->animScale);
break;
}
MTX_Scale43(&sclMat, sclX, sclY, sclY);
MTX_Concat43(&sclMat, &rotMat, &load);
if (!mgr->renderState.emitter->resource->header->flags.useViewSpace) {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
G3_LoadMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
} else {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
G3_Identity();
G3_Translate(
mgr->renderState.emitter->resource->header->emitterBasePos.x,
mgr->renderState.emitter->resource->header->emitterBasePos.y,
mgr->renderState.emitter->resource->header->emitterBasePos.z);
G3_MultMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
}
G3_Color(GX_RGB(
GX_RGB_R_(ptcl->color) * GX_RGB_R_(mgr->renderState.emitter->color) >> 5,
GX_RGB_G_(ptcl->color) * GX_RGB_G_(mgr->renderState.emitter->color) >> 15,
GX_RGB_B_(ptcl->color) * GX_RGB_B_(mgr->renderState.emitter->color) >> 25));
sPlaneDrawingFunctions[mgr->renderState.emitter->resource->header->flags.polygonReferencePlane](
mgr->renderState.emitter->textureS,
mgr->renderState.emitter->textureT,
mgr->renderState.emitter->resource->header->polygonX,
mgr->renderState.emitter->resource->header->polygonY);
}
void SPLDraw_Child_Polygon(SPLManager *mgr, SPLParticle *ptcl)
{
fx32 sclX, sclY;
MtxFx43 load;
MtxFx43 rotMat;
MtxFx43 sclMat;
if (SPLDraw_Setup(ptcl, mgr)) {
return;
}
sRotationFunctions[mgr->renderState.emitter->resource->childResource->flags.polygonRotAxis](
FX_SinIdx(ptcl->rotation),
FX_CosIdx(ptcl->rotation),
&rotMat);
sclY = ptcl->baseScale;
sclX = FX_MUL(sclY, mgr->renderState.emitter->resource->header->aspectRatio);
switch (mgr->renderState.emitter->resource->header->misc.scaleAnimDir) {
case SPL_SCALE_ANIM_DIR_XY:
sclX = FX_MUL(sclX, ptcl->animScale);
sclY = FX_MUL(sclY, ptcl->animScale);
break;
case SPL_SCALE_ANIM_DIR_X:
sclX = FX_MUL(sclX, ptcl->animScale);
break;
case SPL_SCALE_ANIM_DIR_Y:
sclY = FX_MUL(sclY, ptcl->animScale);
break;
}
MTX_Scale43(&sclMat, sclX, sclY, sclY);
MTX_Concat43(&rotMat, &sclMat, &load);
if (!mgr->renderState.emitter->resource->header->flags.useViewSpace) {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
G3_LoadMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
} else {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
G3_Identity();
G3_Translate(
mgr->renderState.emitter->resource->header->emitterBasePos.x,
mgr->renderState.emitter->resource->header->emitterBasePos.y,
mgr->renderState.emitter->resource->header->emitterBasePos.z);
G3_MultMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&load);
}
G3_Color(GX_RGB(
GX_RGB_R_(ptcl->color) * GX_RGB_R_(mgr->renderState.emitter->color) >> 5,
GX_RGB_G_(ptcl->color) * GX_RGB_G_(mgr->renderState.emitter->color) >> 15,
GX_RGB_B_(ptcl->color) * GX_RGB_B_(mgr->renderState.emitter->color) >> 25));
sPlaneDrawingFunctions[mgr->renderState.emitter->resource->childResource->flags.polygonReferencePlane](
mgr->renderState.emitter->childTextureS,
mgr->renderState.emitter->childTextureT,
0,
0);
}
void SPLDraw_DirectionalPolygon(SPLManager *mgr, SPLParticle *ptcl)
{
MtxFx43 load;
MtxFx43 rotMat;
MtxFx43 sclMat;
VecFx32 unitDir, dir1, dir2, dir3, axis;
MtxFx43 mat;
fx32 sclX, sclY;
if (SPLDraw_Setup(ptcl, mgr)) {
return;
}
sRotationFunctions[mgr->renderState.emitter->resource->header->flags.polygonRotAxis](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMat);
MTX_Identity43(&mat);
if (!mgr->renderState.emitter->resource->header->misc.unk_07_7) {
VEC_Normalize(&ptcl->velocity, &vec1);
if (!mgr->renderState.emitter->resource->header->misc.dpolFaceEmitter) {
VEC_Normalize(&ptcl->velocity, &unitDir);
} else {
VEC_Normalize(&ptcl->position, &vec1);
vec1.x = -vec1.x;
vec1.y = -vec1.y;
vec1.z = -vec1.z;
VEC_Normalize(&ptcl->position, &unitDir);
unitDir.x = -unitDir.x;
unitDir.y = -unitDir.y;
unitDir.z = -unitDir.z;
}
axis.x = 0;
axis.y = FX32_ONE;
axis.z = 0;
dot = VEC_DotProduct(&vec1, &axis);
fx32 dot = VEC_DotProduct(&unitDir, &axis);
if (dot > FX32_CONST(0.8) || dot < FX32_CONST(-0.8)) {
axis.x = FX32_ONE;
axis.y = 0;
axis.z = 0;
}
VEC_CrossProduct(&vec1, &axis, &vec2);
VEC_CrossProduct(&vec1, &vec2, &vec3);
VEC_CrossProduct(&unitDir, &axis, &dir1);
VEC_CrossProduct(&unitDir, &dir1, &dir2);
mat.m[0][0] = vec2.x;
mat.m[0][1] = vec2.y;
mat.m[0][2] = vec2.z;
mat.m[1][0] = vec1.x;
mat.m[1][1] = vec1.y;
mat.m[1][2] = vec1.z;
mat.m[2][0] = vec3.x;
mat.m[2][1] = vec3.y;
mat.m[2][2] = vec3.z;
mat.m[0][0] = dir1.x;
mat.m[0][1] = dir1.y;
mat.m[0][2] = dir1.z;
mat.m[1][0] = unitDir.x;
mat.m[1][1] = unitDir.y;
mat.m[1][2] = unitDir.z;
mat.m[2][0] = dir2.x;
mat.m[2][1] = dir2.y;
mat.m[2][2] = dir2.z;
MTX_Concat43(&rotMat, &mat, &rotMat);
resBase = mgr->renderState.emitter->resource->header;
scaleY = ptcl->baseScale;
scaleX = FX_MUL(scaleY, resBase->aspectRatio);
sclY = ptcl->baseScale;
sclX = FX_MUL(sclY, mgr->renderState.emitter->resource->header->aspectRatio);
switch (resBase->misc.scaleAnimDir) {
case 0:
scaleX = FX_MUL(scaleX, ptcl->animScale);
scaleY = FX_MUL(scaleY, ptcl->animScale);
switch (mgr->renderState.emitter->resource->header->misc.scaleAnimDir) {
case SPL_SCALE_ANIM_DIR_XY:
sclX = FX_MUL(sclX, ptcl->animScale);
sclY = FX_MUL(sclY, ptcl->animScale);
break;
case 1:
scaleX = FX_MUL(scaleX, ptcl->animScale);
case SPL_SCALE_ANIM_DIR_X:
sclX = FX_MUL(sclX, ptcl->animScale);
break;
case 2:
scaleY = FX_MUL(scaleY, ptcl->animScale);
case SPL_SCALE_ANIM_DIR_Y:
sclY = FX_MUL(sclY, ptcl->animScale);
break;
}
MTX_Scale43(&sclMat, scaleX, scaleY, scaleY);
MTX_Concat43(&sclMat, &rotMat, &transform);
MTX_Scale43(&sclMat, sclX, sclY, sclY);
MTX_Concat43(&sclMat, &rotMat, &load);
if (!mgr->renderState.emitter->resource->header->flags.useViewSpace) {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
resBase = mgr->renderState.emitter->resource->header;
if (!resBase->flags.useViewSpace) {
transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
G3_LoadMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&transform);
G3_MultMtx43(&load);
} else {
transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - resBase->emitterBasePos.x;
transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
G3_Identity();
resBase = mgr->renderState.emitter->resource->header;
G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z);
G3_Translate(
mgr->renderState.emitter->resource->header->emitterBasePos.x,
mgr->renderState.emitter->resource->header->emitterBasePos.y,
mgr->renderState.emitter->resource->header->emitterBasePos.z);
G3_MultMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&transform);
G3_MultMtx43(&load);
}
colA = ptcl->color;
colB = mgr->renderState.emitter->color;
G3_Color(GX_RGB(
GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5,
GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15,
GX_RGB_B_(colA) * GX_RGB_B_(colB) >> 25));
GX_RGB_R_(ptcl->color) * GX_RGB_R_(mgr->renderState.emitter->color) >> 5,
GX_RGB_G_(ptcl->color) * GX_RGB_G_(mgr->renderState.emitter->color) >> 15,
GX_RGB_B_(ptcl->color) * GX_RGB_B_(mgr->renderState.emitter->color) >> 25));
emtr = mgr->renderState.emitter;
resBase = emtr->resource->header;
sPlaneDrawingFunctions[resBase->flags.unk_06_3](emtr->textureS, emtr->textureT, resBase->polygonX, resBase->polygonY);
sPlaneDrawingFunctions[mgr->renderState.emitter->resource->header->flags.polygonReferencePlane](
mgr->renderState.emitter->textureS,
mgr->renderState.emitter->textureT,
mgr->renderState.emitter->resource->header->polygonX,
mgr->renderState.emitter->resource->header->polygonY);
}
void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl)
void SPLDraw_Child_DirectionalPolygon(SPLManager *mgr, SPLParticle *ptcl)
{
MtxFx43 transform;
MtxFx43 rotMtx;
MtxFx43 load;
MtxFx43 rotMat;
MtxFx43 sclMat;
VecFx32 vec1, vec2, vec3, vec4, axis;
VecFx32 unitDir, dir1, dir2, dir3, axis;
MtxFx43 mat;
fx32 dot, scaleX, scaleY, scaleZ, alpha, tmp;
SPLResourceHeader *resBase;
fx32 sclX, sclY;
alpha = ptcl->visibility.baseAlpha * (ptcl->visibility.animAlpha + 1) >> 5;
G3_PolygonAttr(
GX_LIGHTMASK_NONE,
GX_POLYGONMODE_MODULATE,
GX_CULL_NONE,
ptcl->visibility.currentPolygonID,
alpha,
mgr->miscPolygonAttr);
reg_G3_POLYGON_ATTR;
if (alpha == 0) {
if (SPLDraw_Setup(ptcl, mgr)) {
return;
}
sRotationFunctions[mgr->renderState.emitter->resource->childResource->flags.unk_03_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMtx);
sRotationFunctions[mgr->renderState.emitter->resource->childResource->flags.polygonRotAxis](
FX_SinIdx(ptcl->rotation),
FX_CosIdx(ptcl->rotation),
&rotMat);
MTX_Identity43(&mat);
if (!mgr->renderState.emitter->resource->childResource->misc.unk_04_6) {
VEC_Normalize(&ptcl->velocity, &vec1);
if (!mgr->renderState.emitter->resource->childResource->misc.dpolFaceEmitter) {
VEC_Normalize(&ptcl->velocity, &unitDir);
} else {
VEC_Normalize(&ptcl->position, &vec1);
vec1.x = -vec1.x;
vec1.y = -vec1.y;
vec1.z = -vec1.z;
VEC_Normalize(&ptcl->position, &unitDir);
unitDir.x = -unitDir.x;
unitDir.y = -unitDir.y;
unitDir.z = -unitDir.z;
}
axis.x = 0;
axis.y = FX32_ONE;
axis.z = 0;
dot = VEC_DotProduct(&vec1, &axis);
fx32 dot = VEC_DotProduct(&unitDir, &axis);
if (dot > FX32_CONST(0.8) || dot < FX32_CONST(-0.8)) {
axis.x = FX32_ONE;
axis.y = 0;
axis.z = 0;
}
VEC_CrossProduct(&vec1, &axis, &vec2);
VEC_CrossProduct(&vec1, &vec2, &vec3);
VEC_CrossProduct(&unitDir, &axis, &dir1);
VEC_CrossProduct(&unitDir, &dir1, &dir2);
mat.m[0][0] = vec2.x;
mat.m[0][1] = vec2.y;
mat.m[0][2] = vec2.z;
mat.m[1][0] = vec1.x;
mat.m[1][1] = vec1.y;
mat.m[1][2] = vec1.z;
mat.m[2][0] = vec3.x;
mat.m[2][1] = vec3.y;
mat.m[2][2] = vec3.z;
MTX_Concat43(&rotMtx, &mat, &rotMtx);
mat.m[0][0] = dir1.x;
mat.m[0][1] = dir1.y;
mat.m[0][2] = dir1.z;
mat.m[1][0] = unitDir.x;
mat.m[1][1] = unitDir.y;
mat.m[1][2] = unitDir.z;
mat.m[2][0] = dir2.x;
mat.m[2][1] = dir2.y;
mat.m[2][2] = dir2.z;
MTX_Concat43(&rotMat, &mat, &rotMat);
resBase = mgr->renderState.emitter->resource->header;
scaleY = ptcl->baseScale;
scaleX = FX_MUL(scaleY, resBase->aspectRatio);
sclY = ptcl->baseScale;
sclX = FX_MUL(sclY, mgr->renderState.emitter->resource->header->aspectRatio);
switch (resBase->misc.scaleAnimDir) {
case 0:
scaleX = FX_MUL(scaleX, ptcl->animScale);
scaleY = FX_MUL(scaleY, ptcl->animScale);
switch (mgr->renderState.emitter->resource->header->misc.scaleAnimDir) {
case SPL_SCALE_ANIM_DIR_XY:
sclX = FX_MUL(sclX, ptcl->animScale);
sclY = FX_MUL(sclY, ptcl->animScale);
break;
case 1:
scaleX = FX_MUL(scaleX, ptcl->animScale);
case SPL_SCALE_ANIM_DIR_X:
sclX = FX_MUL(sclX, ptcl->animScale);
break;
case 2:
scaleY = FX_MUL(scaleY, ptcl->animScale);
case SPL_SCALE_ANIM_DIR_Y:
sclY = FX_MUL(sclY, ptcl->animScale);
break;
}
MTX_Scale43(&sclMat, scaleX, scaleY, scaleY);
MTX_Concat43(&rotMtx, &sclMat, &transform);
MTX_Scale43(&sclMat, sclX, sclY, sclY);
MTX_Concat43(&rotMat, &sclMat, &load);
if (!mgr->renderState.emitter->resource->header->flags.useViewSpace) {
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
resBase = mgr->renderState.emitter->resource->header;
if (!resBase->flags.useViewSpace) {
transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x;
transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y;
transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z;
G3_LoadMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&transform);
G3_MultMtx43(&load);
} else {
transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - resBase->emitterBasePos.x;
transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x;
load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y;
load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z;
G3_Identity();
resBase = mgr->renderState.emitter->resource->header;
G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z);
G3_Translate(
mgr->renderState.emitter->resource->header->emitterBasePos.x,
mgr->renderState.emitter->resource->header->emitterBasePos.y,
mgr->renderState.emitter->resource->header->emitterBasePos.z);
G3_MultMtx43(mgr->renderState.viewMatrix);
G3_MultMtx43(&transform);
G3_MultMtx43(&load);
}
GXRgb colA = ptcl->color;
GXRgb colB = mgr->renderState.emitter->color;
G3_Color(GX_RGB(
GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5,
GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15,
GX_RGB_B_(colA) * GX_RGB_B_(colB) >> 25));
GX_RGB_R_(ptcl->color) * GX_RGB_R_(mgr->renderState.emitter->color) >> 5,
GX_RGB_G_(ptcl->color) * GX_RGB_G_(mgr->renderState.emitter->color) >> 15,
GX_RGB_B_(ptcl->color) * GX_RGB_B_(mgr->renderState.emitter->color) >> 25));
SPLEmitter *emtr = mgr->renderState.emitter;
sPlaneDrawingFunctions[emtr->resource->childResource->flags.unk_03_3](emtr->childTextureS, emtr->childTextureT, 0, 0);
sPlaneDrawingFunctions[mgr->renderState.emitter->resource->childResource->flags.polygonReferencePlane](
mgr->renderState.emitter->childTextureS,
mgr->renderState.emitter->childTextureT,
0,
0);
}