Create material interp module, drop various per-actor callbacks

This commit is contained in:
Irastris
2026-09-12 22:08:00 -04:00
parent bbb1d735e5
commit a1938ffd13
23 changed files with 967 additions and 262 deletions
+1
View File
@@ -1467,6 +1467,7 @@ set(DUSK_FILES
src/dusk/interp/camera.cpp
src/dusk/interp/frame_interpolation.cpp
src/dusk/interp/line.cpp
src/dusk/interp/material.cpp
src/dusk/interp/particle.cpp
src/dusk/interp/samples.cpp
src/dusk/interp/vertex.cpp
-3
View File
@@ -370,9 +370,6 @@ public:
u32 getAngleNoFromParam() { return (u8)(fopAcM_GetParam(this) >> 8); }
void setBlastFlag(u8 i_flag) { mBlastFlag = i_flag; }
MtxP getHeadMtx() { return mAnm_p->getModel()->getAnmMtx(4); }
#if TARGET_PC
friend void daNpc_zrA_interp_callback(void* pUserWork);
#endif
/* 0x0B48 */ Z2Creature mCreatureSound;
/* 0x0BD8 */ J3DModel* mpObjectModel[3];
-3
View File
@@ -58,9 +58,6 @@ public:
void setNextPoint();
int Draw();
int Delete();
#if TARGET_PC
friend void daL8Lift_interp_callback(void* pUserWork);
#endif
u8 getPthID() { return fopAcM_GetParamBit(this, 0, 8); }
u8 getMoveSpeed() { return fopAcM_GetParamBit(this, 8, 4); }
+14 -2
View File
@@ -80,7 +80,13 @@ public:
int remove(J3DModelData* i_modelData) { return i_modelData->removeTexMtxAnimator(mpAnm); }
void entryFrame() { entryFrame(getFrame()); }
void entryFrame(f32 frame) { mpAnm->setFrame(frame); }
#if TARGET_PC
void entryFrame(f32 frame);
#else
void entryFrame(f32 frame) {
mpAnm->setFrame(frame);
}
#endif
J3DAnmTextureSRTKey* getBtkAnm() const { return mpAnm; }
@@ -110,7 +116,13 @@ public:
int remove(J3DModelData* i_modelData) { return i_modelData->removeTevRegAnimator(mpAnm); }
void entryFrame() { entryFrame(getFrame()); }
void entryFrame(f32 frame) { mpAnm->setFrame(frame); }
#if TARGET_PC
void entryFrame(f32 frame);
#else
void entryFrame(f32 frame) {
mpAnm->setFrame(frame);
}
#endif
J3DAnmTevRegKey* getBrkAnm() const { return mpAnm; }
@@ -6,9 +6,9 @@
#include <mtx.h>
#include "global.h"
#if TARGET_PC
#include "helpers/endian.h"
#if TARGET_PC
#define OFFSET_PTR_V0 BE(u32)
#else
#define OFFSET_PTR_V0 void*
@@ -478,27 +478,45 @@ struct J3DAnmClusterFullTable {
*/
class J3DAnmBase {
public:
#if TARGET_PC
J3DAnmBase();
#else
J3DAnmBase() {
mAttribute = 0;
field_0x5 = 0;
mFrameMax = 0;
mFrame = 0.0f;
}
#endif
#if TARGET_PC
J3DAnmBase(s16 frameMax);
#else
J3DAnmBase(s16 frameMax) {
mAttribute = 0;
field_0x5 = 0;
mFrameMax = frameMax;
mFrame = 0.0f;
}
#endif
#if TARGET_PC
virtual ~J3DAnmBase();
#else
virtual ~J3DAnmBase() {}
#endif
virtual s32 getKind() const = 0;
u8 getAttribute() const { return mAttribute; }
s16 getFrameMax() const { return mFrameMax; }
f32 getFrame() const { return mFrame; }
void setFrame(f32 frame) { mFrame = frame; }
#if TARGET_PC
void setFrame(f32 frame);
#else
void setFrame(f32 frame) {
mFrame = frame;
}
#endif
/* 0x4 */ u8 mAttribute;
/* 0x5 */ u8 field_0x5;
@@ -960,30 +978,66 @@ public:
void init(int endFrame) { init((s16)endFrame); }
BOOL checkPass(f32);
void update();
#if TARGET_PC
virtual ~J3DFrameCtrl();
#else
virtual ~J3DFrameCtrl() {}
#endif
u8 getAttribute() const { return mAttribute; }
void setAttribute(u8 attr) { mAttribute = attr; }
#if TARGET_PC
void setAttribute(u8 attr);
#else
void setAttribute(u8 attr) {
mAttribute = attr;
}
#endif
u8 getState() const { return mState; }
bool checkState(u8 state) const { return mState & state ? true : false; }
s16 getStart() const { return mStart; }
#if TARGET_PC
void setStart(s16 start);
#else
void setStart(s16 start) {
mStart = start;
mFrame = start;
}
#endif
s16 getEnd() const { return mEnd; }
void setEnd(s16 end) { mEnd = end; }
#if TARGET_PC
void setEnd(s16 end);
#else
void setEnd(s16 end) {
mEnd = end;
}
#endif
s16 getLoop() const { return mLoop; }
void setLoop(s16 loop) { mLoop = loop; }
#if TARGET_PC
void setLoop(s16 loop);
#else
void setLoop(s16 loop) {
mLoop = loop;
}
#endif
f32 getRate() const { return mRate; }
void setRate(f32 rate) { mRate = rate; }
f32 getFrame() const { return mFrame; }
void setFrame(f32 frame) { mFrame = frame; }
#if TARGET_PC
void setFrame(f32 frame);
#else
void setFrame(f32 frame) {
mFrame = frame;
}
#endif
#if TARGET_PC
void reset();
#else
void reset() {
mFrame = mStart;
mRate = 1.0f;
mState = 0;
}
#endif
/* 0x04 */ u8 mAttribute;
/* 0x05 */ u8 mState;
@@ -31,10 +31,15 @@ public:
void setAnmFlag(bool flag) { mAnmFlag = flag; }
bool getAnmFlag() const { return mAnmFlag; }
#if TARGET_PC
void calc(GXColor* pColor) const;
J3DAnmColor* getAnimation() const { return mAnmColor; }
#else
void calc(GXColor* pColor) const {
J3D_ASSERT_NULLPTR(507, pColor != NULL);
mAnmColor->getColor(field_0x0, pColor);
}
#endif
private:
/* 0x0 */ u16 field_0x0;
@@ -66,10 +71,15 @@ public:
void setAnmFlag(bool flag) { mAnmFlag = flag; }
#if TARGET_PC
void calc(J3DTextureSRTInfo* pSRTInfo) const;
J3DAnmTextureSRTKey* getAnimation() const { return mAnmTransform; }
#else
void calc(J3DTextureSRTInfo* pSRTInfo) const {
J3D_ASSERT_NULLPTR(519, pSRTInfo != NULL);
mAnmTransform->getTransform(field_0x0, pSRTInfo);
}
#endif
bool getAnmFlag() const { return mAnmFlag; }
@@ -108,6 +118,9 @@ public:
void setAnmFlag(bool flag) { mAnmFlag = flag; }
bool getAnmFlag() const { return mAnmFlag; }
#if TARGET_PC
J3DAnmTexPattern* getAnimation() const { return mAnmTexPattern; }
#endif
J3DAnmTexPattern* getAnmTexPattern() { return mAnmTexPattern; }
private:
@@ -141,10 +154,15 @@ public:
void setAnmFlag(bool flag) { mAnmFlag = flag; }
bool getAnmFlag() const { return mAnmFlag; }
#if TARGET_PC
void calc(GXColorS10* pColor) const;
J3DAnmTevRegKey* getAnimation() const { return mAnmTevReg; }
#else
void calc(GXColorS10* pColor) const {
J3D_ASSERT_NULLPTR(545, pColor != NULL);
mAnmTevReg->getTevColorReg(field_0x0, pColor);
}
#endif
private:
/* 0x0 */ u16 field_0x0;
@@ -177,10 +195,15 @@ public:
void setAnmFlag(bool flag) { mAnmFlag = flag; }
bool getAnmFlag() const { return mAnmFlag; }
#if TARGET_PC
void calc(GXColor* pColor) const;
J3DAnmTevRegKey* getAnimation() const { return mAnmTevReg; }
#else
void calc(GXColor* pColor) const {
J3D_ASSERT_NULLPTR(558, pColor != NULL);
mAnmTevReg->getTevKonstReg(field_0x0, pColor);
}
#endif
private:
/* 0x0 */ u16 field_0x0;
@@ -197,6 +220,9 @@ public:
J3DMaterialAnm() { initialize(); }
void initialize();
#if TARGET_PC
bool hasMaterialAnimation() const;
#endif
void setMatColorAnm(int, J3DMatColorAnm*);
void setTexMtxAnm(int, J3DTexMtxAnm*);
void setTexNoAnm(int, J3DTexNoAnm*);
@@ -207,6 +233,12 @@ public:
virtual void calc(J3DMaterial*) const;
const J3DTexMtxAnm& getTexMtxAnm(int i) const { return mTexMtxAnm[i]; }
#if TARGET_PC
const J3DMatColorAnm& getMatColorAnm(int i) const { return mMatColorAnm[i]; }
const J3DTexNoAnm& getTexNoAnm(int i) const { return mTexNoAnm[i]; }
const J3DTevColorAnm& getTevColorAnm(int i) const { return mTevColorAnm[i]; }
const J3DTevKColorAnm& getTevKColorAnm(int i) const { return mTevKColorAnm[i]; }
#endif
private:
/* 0x04 */ J3DMatColorAnm mMatColorAnm[2];
@@ -79,7 +79,6 @@ public:
virtual ~J3DModel() {}
#if TARGET_PC
static void interp_callback(void* pUserWork);
void calc_presentation_base_mtx();
void prepare_presentation_view();
#endif
@@ -5,7 +5,12 @@
#include "JSystem/J3DGraphBase/J3DStruct.h"
#include "JSystem/JMath/JMath.h"
#if TARGET_PC
#include "dusk/interp/material.h"
#endif
void J3DFrameCtrl::init(s16 endFrame) {
IF_DUSK(dusk::interp::material::reset(this));
mAttribute = EMode_LOOP;
mState = 0;
mStart = 0;
@@ -134,6 +139,7 @@ int J3DFrameCtrl::checkPass(f32 passFrame) {
void J3DFrameCtrl::update() {
IF_DUSK(dusk::interp::material::Update materialUpdate(*this));
mState = 0;
mFrame += mRate;
@@ -1456,3 +1462,67 @@ void J3DAnmTevRegKey::searchUpdateMaterialID(J3DModelData* pModelData) {
J3D_ASSERT_NULLPTR(2119, pModelData != NULL);
searchUpdateMaterialID(&pModelData->getMaterialTable());
}
#if TARGET_PC
J3DAnmBase::J3DAnmBase() {
dusk::interp::material::reset(this);
mAttribute = 0;
field_0x5 = 0;
mFrameMax = 0;
mFrame = 0.0f;
}
J3DAnmBase::J3DAnmBase(s16 frameMax) {
dusk::interp::material::reset(this);
mAttribute = 0;
field_0x5 = 0;
mFrameMax = frameMax;
mFrame = 0.0f;
}
J3DAnmBase::~J3DAnmBase() {
dusk::interp::material::reset(this);
}
void J3DAnmBase::setFrame(f32 frame) {
dusk::interp::material::reset(this);
mFrame = frame;
}
J3DFrameCtrl::~J3DFrameCtrl() {
dusk::interp::material::reset(this);
}
void J3DFrameCtrl::setAttribute(u8 attr) {
dusk::interp::material::reset(this);
mAttribute = attr;
}
void J3DFrameCtrl::setStart(s16 start) {
dusk::interp::material::reset(this);
mStart = start;
mFrame = start;
}
void J3DFrameCtrl::setEnd(s16 end) {
dusk::interp::material::reset(this);
mEnd = end;
}
void J3DFrameCtrl::setLoop(s16 loop) {
dusk::interp::material::reset(this);
mLoop = loop;
}
void J3DFrameCtrl::setFrame(f32 frame) {
dusk::interp::material::reset(this);
mFrame = frame;
}
void J3DFrameCtrl::reset() {
dusk::interp::material::reset(this);
mFrame = mStart;
mRate = 1.0f;
mState = 0;
}
#endif
@@ -3,6 +3,10 @@
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#if TARGET_PC
#include "dusk/interp/material.h"
#endif
void J3DMaterialAnm::initialize() {
for (int i = 0; i < ARRAY_SIZE(mMatColorAnm); i++) {
mMatColorAnm[i].setAnmFlag(false);
@@ -114,3 +118,44 @@ void J3DMaterialAnm::setTevKColorAnm(int idx, J3DTevKColorAnm* pTevKColorAnm) {
mTevKColorAnm[idx] = *pTevKColorAnm;
}
}
#if TARGET_PC
bool J3DMaterialAnm::hasMaterialAnimation() const {
for (const auto& track : mMatColorAnm) {
if (track.getAnmFlag()) return true;
}
for (const auto& track : mTexMtxAnm) {
if (track.getAnmFlag()) return true;
}
for (const auto& track : mTevColorAnm) {
if (track.getAnmFlag()) return true;
}
for (const auto& track : mTevKColorAnm) {
if (track.getAnmFlag()) return true;
}
return false;
}
void J3DMatColorAnm::calc(GXColor* pColor) const {
J3D_ASSERT_NULLPTR(507, pColor != NULL);
dusk::interp::material::Sample materialSample(mAnmColor);
mAnmColor->getColor(field_0x0, pColor);
}
void J3DTexMtxAnm::calc(J3DTextureSRTInfo* pSRTInfo) const {
J3D_ASSERT_NULLPTR(519, pSRTInfo != NULL);
dusk::interp::material::sample_texture(mAnmTransform, field_0x0, pSRTInfo);
}
void J3DTevColorAnm::calc(GXColorS10* pColor) const {
J3D_ASSERT_NULLPTR(545, pColor != NULL);
dusk::interp::material::Sample materialSample(mAnmTevReg);
mAnmTevReg->getTevColorReg(field_0x0, pColor);
}
void J3DTevKColorAnm::calc(GXColor* pColor) const {
J3D_ASSERT_NULLPTR(558, pColor != NULL);
dusk::interp::material::Sample materialSample(mAnmTevReg);
mAnmTevReg->getTevKonstReg(field_0x0, pColor);
}
#endif
+12 -8
View File
@@ -11,6 +11,7 @@
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#include "dusk/interp/material.h"
#include "dusk/interp/vertex.h"
#endif
@@ -103,12 +104,6 @@ s32 J3DModel::entryModelData(J3DModelData* pModelData, u32 mdlFlags, u32 mtxNum)
}
#if TARGET_PC
void J3DModel::interp_callback(void* pUserWork) {
J3DModel* i_this = static_cast<J3DModel*>(pUserWork);
i_this->calcMaterial();
i_this->diff();
}
void J3DModel::calc_presentation_base_mtx() {
Mtx identity;
MTXIdentity(identity);
@@ -327,7 +322,16 @@ void J3DModel::calcMaterial() {
material->getMaterialAnm()->calc(material);
}
material->calc(getAnmMtx(material->getJoint()->getJntNo()));
MtxP jointMtx = getAnmMtx(material->getJoint()->getJntNo());
#if TARGET_PC
Mtx presentedJoint;
if (dusk::interp::is_presentation_active() &&
dusk::interp::lookup_replacement(jointMtx, presentedJoint))
{
jointMtx = presentedJoint;
}
#endif
material->calc(jointMtx);
}
}
@@ -536,7 +540,7 @@ void J3DModel::entry() {
#if TARGET_PC
if (mModelData->needsInterpCallBack()) {
dusk::interp::add_interpolation_callback(&J3DModel::interp_callback, this);
dusk::interp::material::record_model(this);
}
#endif
}
@@ -4,6 +4,10 @@
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "JSystem/JKernel/JKRHeap.h"
#if TARGET_PC
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
#endif
J3DColorBlock* J3DMaterial::createColorBlock(u32 flags) {
J3DColorBlock* rv = NULL;
switch (flags) {
@@ -367,6 +371,9 @@ s32 J3DMaterial::newSingleSharedDisplayList(u32 dlSize) {
#if TARGET_PC
bool J3DMaterial::needsInterpCallBack() const {
if (mMaterialAnm != nullptr && mMaterialAnm->hasMaterialAnimation()) {
return true;
}
for (int i = 0, n = getTexGenNum(); i < n; i++) {
J3DTexMtx* pTexMtx = mTexGenBlock->getTexMtx(i);
if (pTexMtx != NULL) {
-57
View File
@@ -14,10 +14,6 @@
#include "f_op/f_op_camera_mng.h"
#include <cstring>
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
class daE_SM2_HIO_c : public fOpAcm_HIO_entry_c {
public:
daE_SM2_HIO_c();
@@ -80,62 +76,9 @@ static int nodeCallBack(J3DJoint* i_joint, int param_1) {
return 1;
}
#if TARGET_PC
static void daE_SM2_interp_callback(void* pUserWork) {
e_sm2_class* i_this = static_cast<e_sm2_class*>(pUserWork);
if (i_this == NULL) {
return;
}
fopAc_ac_c* actor = (fopAc_ac_c*)&i_this->enemy;
g_env_light.settingTevStruct(0, &actor->current.pos, &actor->tevStr);
if (!i_this->isPiece) {
if (i_this->modelMorf == NULL) {
return;
}
J3DModel* model = i_this->modelMorf->getModel();
if (model == NULL) {
return;
}
g_env_light.setLightTevColorType_MAJI(model, &actor->tevStr);
J3DMaterial* material = model->getModelData()->getMaterialNodePointer(0);
material->getTevKColor(1)->r = i_this->color_R;
material->getTevKColor(1)->g = i_this->color_G;
material->getTevKColor(1)->b = i_this->color_B;
material->getTevKColor(1)->a = 217.0f * i_this->color_alpha;
if (i_this->pbtk != NULL) {
i_this->pbtk->entry(model->getModelData());
}
} else {
if (i_this->pieceModelMorf == NULL) {
return;
}
J3DModel* model = i_this->pieceModelMorf->getModel();
if (model == NULL) {
return;
}
J3DMaterial* material = model->getModelData()->getMaterialNodePointer(0);
material->getTevKColor(1)->r = i_this->color_R;
material->getTevKColor(1)->g = i_this->color_G;
material->getTevKColor(1)->b = i_this->color_B;
material->getTevKColor(1)->a = 217.0f * i_this->color_alpha;
g_env_light.setLightTevColorType_MAJI(model, &actor->tevStr);
}
}
#endif
static int daE_SM2_Draw(e_sm2_class* i_this) {
fopAc_ac_c* actor = (fopAc_ac_c*)&i_this->enemy;
#if TARGET_PC
dusk::interp::add_interpolation_callback(&daE_SM2_interp_callback, i_this);
#endif
g_env_light.settingTevStruct(0, &actor->current.pos, &actor->tevStr);
J3DModel* model;
-69
View File
@@ -20,10 +20,6 @@
#include "d/actor/d_a_obj_zraMark.h"
#include <cstring>
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
static NPC_ZRA_HIO_CLASS l_HIO;
DUSK_GAME_DATA daNpc_zrA_HIOParam const daNpc_zrA_Param_c::m = {
@@ -690,69 +686,6 @@ int daNpc_zrA_c::Execute() {
return execute();
}
#if TARGET_PC
void daNpc_zrA_interp_callback(void* pUserWork) {
daNpc_zrA_c* i_this = static_cast<daNpc_zrA_c*>(pUserWork);
if (i_this == NULL || i_this->mAnm_p == NULL || i_this->checkHide()) {
return;
}
J3DModel* model = i_this->mAnm_p->getModel();
if (model == NULL) {
return;
}
J3DModelData* model_data = model->getModelData();
model_data->getMaterialNodePointer(1)->setMaterialAnm(i_this->mpMatAnm);
if (i_this->mTwilight) {
g_env_light.settingTevStruct(4, &i_this->current.pos, &i_this->tevStr);
} else {
g_env_light.settingTevStruct(0, &i_this->current.pos, &i_this->tevStr);
}
g_env_light.setLightTevColorType_MAJI(model, &i_this->tevStr);
if (i_this->mWaterAnmFlags & daNpcF_c::ANM_PLAY_BTK) {
i_this->mWaterBtkAnm.entry(model_data);
}
if (i_this->mWaterAnmFlags & daNpcF_c::ANM_PLAY_BPK) {
i_this->mWaterBpkAnm.entry(model_data);
}
if (i_this->mAnmFlags & daNpcF_c::ANM_PLAY_BTP) {
i_this->mBtpAnm.entry(model_data);
}
if (i_this->mAnmFlags & daNpcF_c::ANM_PLAY_BTK) {
i_this->mBtkAnm.entry(model_data);
}
if (i_this->mAnmFlags & daNpcF_c::ANM_PLAY_BRK) {
i_this->mBrkAnm.entry(model_data);
}
if (!i_this->mHide && !i_this->mTwilight) {
fopAcM_setEffectMtx(i_this, model_data);
}
model->calcMaterial();
model->diff();
if (i_this->mAnmFlags & daNpcF_c::ANM_PLAY_BTP) {
i_this->mBtpAnm.remove(model_data);
}
if (i_this->mAnmFlags & daNpcF_c::ANM_PLAY_BTK) {
i_this->mBtkAnm.remove(model_data);
}
if (i_this->mAnmFlags & daNpcF_c::ANM_PLAY_BRK) {
i_this->mBrkAnm.remove(model_data);
}
if (i_this->mWaterAnmFlags & daNpcF_c::ANM_PLAY_BPK) {
i_this->mWaterBpkAnm.remove(model_data);
}
if (i_this->mWaterAnmFlags & daNpcF_c::ANM_PLAY_BTK) {
i_this->mWaterBtkAnm.remove(model_data);
}
}
#endif
int daNpc_zrA_c::Draw() {
BOOL bvar2 = false;
J3DModel* model = mAnm_p->getModel();
@@ -804,8 +737,6 @@ int daNpc_zrA_c::Draw() {
mAnm_p->entryDL();
}
IF_DUSK(dusk::interp::add_interpolation_callback(&daNpc_zrA_interp_callback, this));
if (mAnmFlags & ANM_PLAY_BTP) {
mBtpAnm.remove(model_data);
}
+10 -2
View File
@@ -9,6 +9,10 @@
#include "d/d_com_inf_game.h"
#include "m_Do/m_Do_graphic.h"
#if TARGET_PC
#include "dusk/interp/material.h"
#endif
static daGrdWater_HIO_c l_HIO;
static daGrdWater_c::modeFunc l_mode_func[5] = {
@@ -299,13 +303,17 @@ int daGrdWater_c::Draw() {
if (material->getTexGenBlock()->getTexMtx(0) != NULL) {
J3DTexMtxInfo* mtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo();
if (mtxInfo != NULL) {
#if TARGET_PC
dusk::interp::material::set_view_projection(mtxInfo, 1.0f, 1.0f, -0.01f, 0.0f);
#else
Mtx afStack_50;
C_MTXLightPerspective(afStack_50, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect,
1.0f, 1.0f, -0.01f, 0.0f);
#if WIDESCREEN_SUPPORT
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(afStack_50);
#endif
#endif
mtxInfo->setEffectMtx(afStack_50);
#endif
modelData2->simpleCalcMaterial(0, (MtxP)j3dDefaultMtx);
}
}
-29
View File
@@ -16,10 +16,6 @@
#include "f_op/f_op_camera_mng.h"
#include "m_Do/m_Do_mtx.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
static f32 Reflect(cXyz* i_vec, cBgS_PolyInfo const& i_polyinfo, f32 i_scale) {
cM3dGPla plane;
@@ -35,27 +31,6 @@ static f32 Reflect(cXyz* i_vec, cBgS_PolyInfo const& i_polyinfo, f32 i_scale) {
return 0.0f;
}
#if TARGET_PC
static void d_a_obj_item_interp_callback(void* pUserWork) {
daItem_c* item = static_cast<daItem_c*>(pUserWork);
if (item == NULL || item->mpModel == NULL || !item->chkDraw()) {
return;
}
item->setTevStr();
if (item->mpBrkAnm != NULL) {
s8 tevFrm = item->getTevFrm();
if (tevFrm != -1) {
item->mpBrkAnm->entry(item->mpModel->getModelData(), tevFrm);
} else {
item->mpBrkAnm->entry(item->mpModel->getModelData());
}
}
if (item->chkFlag(4)) {
fopAcM_setEffectMtx(item, item->mpModel->getModelData());
}
}
#endif
const daItemBase_data& daItemBase_c::getData() {
return m_data;
}
@@ -411,10 +386,6 @@ int daItem_c::_daItem_draw() {
return 1;
}
#if TARGET_PC
dusk::interp::add_interpolation_callback(&d_a_obj_item_interp_callback, this);
#endif
if (chkDraw()) {
return DrawBase();
}
-41
View File
@@ -10,10 +10,6 @@
#include "d/d_path.h"
#include "d/d_bg_w.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
daL8Lift_HIO_c::daL8Lift_HIO_c() {
mStopDisappearTime = 30;
mStartMoveTime = 60;
@@ -384,44 +380,7 @@ void daL8Lift_c::setNextPoint() {
mCurrentPoint = next_point;
}
#if TARGET_PC
void daL8Lift_interp_callback(void* pUserWork) {
daL8Lift_c* lift = static_cast<daL8Lift_c*>(pUserWork);
if (lift == NULL || lift->mpModel == NULL) {
return;
}
g_env_light.settingTevStruct(0x10, &lift->current.pos, &lift->tevStr);
g_env_light.setLightTevColorType_MAJI(lift->mpModel, &lift->tevStr);
J3DModelData* modelData = lift->mpModel->getModelData();
J3DMaterial* materialp = modelData->getMaterialNodePointer(0);
if (materialp->getTexGenBlock()->getTexMtx(1) != NULL) {
J3DTexMtxInfo* mtx_info = &materialp->getTexGenBlock()->getTexMtx(1)->getTexMtxInfo();
if (mtx_info != NULL) {
Mtx m;
C_MTXLightOrtho(m, 100.0f, -100.0f, -100.0f, 100.0f, 1.0f, 1.0f, 0.0f, 0.0f);
mDoMtx_stack_c::XrotS(0x4000);
mDoMtx_stack_c::transM(-lift->current.pos.x, -lift->current.pos.y, -lift->current.pos.z);
cMtx_concat(m, mDoMtx_stack_c::get(), mtx_info->mEffectMtx);
}
}
lift->mBtk.entry(modelData);
J3DGXColor* color = materialp->getTevKColor(1);
color->r = l_HIO.mColorR;
color->g = l_HIO.mColorG;
color->b = l_HIO.mColorB;
}
#endif
int daL8Lift_c::Draw() {
#if TARGET_PC
dusk::interp::add_interpolation_callback(&daL8Lift_interp_callback, this);
#endif
g_env_light.settingTevStruct(16, &current.pos, &tevStr);
g_env_light.setLightTevColorType_MAJI(mpModel, &tevStr);
J3DModelData* modelData = mpModel->getModelData();
-41
View File
@@ -11,10 +11,6 @@
#include "d/d_com_inf_game.h"
#include "d/d_path.h"
#if TARGET_PC
#include "dusk/interp/frame_interpolation.h"
#endif
daOptiLift_HIO_c::daOptiLift_HIO_c() {
mStopDisappearTime = 30;
mStartMoveTime = 30;
@@ -416,44 +412,7 @@ void daOptiLift_c::setNextPoint() {
mCurrentPoint = next_point;
}
#if TARGET_PC
static void daOptiLift_interp_callback(void* pUserWork) {
daOptiLift_c* lift = static_cast<daOptiLift_c*>(pUserWork);
if (lift == NULL || lift->mpModel == NULL) {
return;
}
g_env_light.settingTevStruct(0x10, &lift->current.pos, &lift->tevStr);
g_env_light.setLightTevColorType_MAJI(lift->mpModel, &lift->tevStr);
J3DModelData* modelData = lift->mpModel->getModelData();
J3DMaterial* materialp = modelData->getMaterialNodePointer(0);
if (materialp->getTexGenBlock()->getTexMtx(1) != NULL) {
J3DTexMtxInfo* mtx_info = &materialp->getTexGenBlock()->getTexMtx(1)->getTexMtxInfo();
if (mtx_info != NULL) {
Mtx m;
C_MTXLightOrtho(m, 100.0f, -100.0f, -100.0f, 100.0f, 1.0f, 1.0f, 0.0f, 0.0f);
mDoMtx_stack_c::XrotS(0x4000);
mDoMtx_stack_c::transM(-lift->current.pos.x, -lift->current.pos.y, -lift->current.pos.z);
cMtx_concat(m, mDoMtx_stack_c::get(), mtx_info->mEffectMtx);
}
}
lift->mBtk.entry(modelData);
J3DGXColor* color = materialp->getTevKColor(1);
color->r = l_HIO.mColorR;
color->g = l_HIO.mColorG;
color->b = l_HIO.mColorB;
}
#endif
int daOptiLift_c::Draw() {
#if TARGET_PC
dusk::interp::add_interpolation_callback(&daOptiLift_interp_callback, this);
#endif
g_env_light.settingTevStruct(0x10, &current.pos, &tevStr);
g_env_light.setLightTevColorType_MAJI(mpModel, &tevStr);
+2
View File
@@ -35,6 +35,7 @@
#if TARGET_PC
#include "dusk/game_clock.h"
#include "dusk/interp/material.h"
#include "dusk/imgui/ImGuiBloomWindow.hpp"
static f32 timeScale = 1.0f;
#endif
@@ -4479,6 +4480,7 @@ static void setLightTevColorType_MAJI_sub(J3DMaterial* material_p, dKy_tevstr_c*
}
}
}
IF_DUSK(dusk::interp::material::record_light_view(material_p));
}
}
+12
View File
@@ -2,6 +2,7 @@
#include "dusk/game_clock.h"
#include "dusk/interp/lerp.h"
#include "dusk/interp/material.h"
#include "dusk/interp/particle.h"
#include "dusk/interp/samples.h"
#include "dusk/interp/vertex.h"
@@ -84,6 +85,7 @@ void interpolate_replacements() {
struct InterpolationCallBackWork {
dusk::interp::InterpolationCallBack pCallBack;
void* pUserWork;
std::shared_ptr<void> owner;
};
std::vector<InterpolationCallBackWork> s_interpolationCallBackWork;
@@ -111,6 +113,7 @@ void clear_interpolation_history() {
dusk::interp::camera_invalidate_snapshots();
dusk::interp::clear_owned_samples();
dusk::interp::clear_weather_samples();
dusk::interp::material::clear();
dusk::interp::particle::clear();
dusk::interp::vertex::clear();
s_presentationDepth = 0;
@@ -129,6 +132,7 @@ void begin_sim_tick() {
clear_callbacks();
camera_on_sim_tick();
++s_simTickSeq;
material::prune();
particle::prune();
vertex::prune();
}
@@ -297,4 +301,12 @@ void add_interpolation_callback(InterpolationCallBack pCallBack, void* pUserWork
s_interpolationCallBackWork.push_back({pCallBack, pUserWork});
}
void add_interpolation_callback(InterpolationCallBack pCallBack, void* pUserWork,
std::shared_ptr<void> owner) {
if (!should_capture() || is_presentation_active() || pCallBack == nullptr) {
return;
}
s_interpolationCallBackWork.push_back({pCallBack, pUserWork, std::move(owner)});
}
} // namespace dusk::interp
+2
View File
@@ -3,6 +3,7 @@
#include <dolphin/mtx.h>
#include <cstdint>
#include <memory>
#ifdef __cplusplus
namespace dusk::interp {
@@ -35,6 +36,7 @@ bool is_presentation_active();
typedef void (*InterpolationCallBack)(void* pUserWork);
void add_interpolation_callback(InterpolationCallBack pCallBack, void* pUserWork);
void add_interpolation_callback(InterpolationCallBack pCallBack, void* pUserWork, std::shared_ptr<void> owner);
} // namespace dusk::interp
#endif
+577
View File
@@ -0,0 +1,577 @@
#include "material.h"
#include "frame_interpolation.h"
#include "dusk/game_clock.h"
#include "d/d_com_inf_game.h"
#include "m_Do/m_Do_graphic.h"
#include "JSystem/J3DGraphAnimator/J3DAnimation.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/J3DGraphAnimator/J3DModelData.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include <algorithm>
#include <cmath>
#include <memory>
#include <tuple>
#include <unordered_map>
#include <utility>
namespace dusk::interp::material {
namespace {
struct ViewProjection {
f32 scaleS, scaleT, transS, transT;
void apply(J3DTexMtxInfo* info) const {
Mtx projection;
const auto* view = dComIfGd_getView();
C_MTXLightPerspective(projection, view->fovy, view->aspect, scaleS, scaleT, transS, transT);
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(projection);
#endif
info->setEffectMtx(projection);
}
};
struct LightView {
Mtx inverse;
void apply(J3DLightInfo* light, bool rotateDirection) const {
Mtx changeOfView;
MTXConcat(j3dSys.getViewMtx(), inverse, changeOfView);
MTXMultVec(changeOfView, &light->mLightPosition, &light->mLightPosition);
if (rotateDirection) {
MTXMultVecSR(changeOfView, &light->mLightDirection, &light->mLightDirection);
}
}
};
struct Tables {
std::unordered_map<const J3DFrameCtrl*, Frames> controllers;
std::unordered_map<const J3DAnmBase*, Frames> resources;
std::unordered_map<J3DTexMtxInfo*, ViewProjection> projections;
std::unordered_map<J3DMaterial*, LightView> lightViews;
};
Tables& tables() {
static Tables stored;
return stored;
}
template <typename Map, typename Key>
Frames lookup(const Map& map, Key key) {
auto it = map.find(key);
return it == map.end() ? Frames{} : it->second;
}
f32 sample_texture_translation(const J3DAnmKeyTableBase& table, const BE(f32)* values, f32 frame, f32 evaluated) {
if (table.mMaxFrame < 2 || table.mType != 1) {
return evaluated;
}
const auto* keys = values + table.mOffset;
for (u16 i = 1; i < table.mMaxFrame; ++i) {
const auto* left = keys + (i - 1) * 4;
const auto* right = left + 4;
if ((f32)left[0] >= frame) {
break;
}
if ((f32)right[0] <= frame || (f32)right[0] - (f32)left[0] != 1.0f) {
continue;
}
const f32 slope = left[2];
const f32 jump = (f32)right[1] - (f32)left[1] - slope;
const f32 tiles = std::round(jump);
if (std::abs((f32)right[3] - slope) < 0.0001f && std::abs(tiles) >= 1.0f &&
std::abs(jump - tiles) < 0.0001f)
{
return (f32)left[1] + slope * (frame - (f32)left[0]);
}
}
return evaluated;
}
} // namespace
Frames get_frames(const J3DFrameCtrl* controller) {
return lookup(tables().controllers, controller);
}
Frames get_frames(const J3DAnmBase* resource) {
return lookup(tables().resources, resource);
}
void reset(const J3DFrameCtrl* controller) {
tables().controllers.erase(controller);
}
void reset(const J3DAnmBase* resource) {
tables().resources.erase(resource);
}
void bind(J3DAnmBase* resource, const J3DFrameCtrl* controller) {
Frames frames = get_frames(controller);
if (frames.valid && frames.tick == sim_tick_seq() &&
frames.epoch == game_clock::g_frameTiming.presentationEpoch)
{
tables().resources[resource] = frames;
} else {
reset(resource);
}
}
void swap_frames(J3DAnmBase* resource, Frames& frames) {
Frames saved = get_frames(resource);
if (frames.valid) {
tables().resources[resource] = frames;
} else {
reset(resource);
}
frames = saved;
}
void clear() {
tables().controllers.clear();
tables().resources.clear();
tables().projections.clear();
tables().lightViews.clear();
}
void prune() {
tables().projections.clear();
tables().lightViews.clear();
const uint64_t tick = sim_tick_seq();
const uint64_t epoch = game_clock::g_frameTiming.presentationEpoch;
auto stale = [=](const auto& entry) {
return entry.second.epoch != epoch || entry.second.tick < tick - (tick != 0);
};
std::erase_if(tables().controllers, stale);
std::erase_if(tables().resources, stale);
}
f32 Frames::read(f32 requested) const {
if (!valid || !smooth || !is_enabled() || !is_presentation_active() || tick != sim_tick_seq() ||
epoch != game_clock::g_frameTiming.presentationEpoch || requested != current)
{
return requested;
}
const f32 step = get_interpolation_step();
if (step <= 0.0f) {
return previous;
}
if (step >= 1.0f) {
return current;
}
f32 frame = previous + (loop ? travel : current - previous) * step;
if (loop && (frame < loopStart || frame >= loopEnd)) {
if ((travel > 0.0f && frame >= loopEnd) || (travel < 0.0f && frame < loopStart)) {
const f32 length = loopEnd - loopStart;
frame = loopStart + std::fmod(frame - loopStart, length);
if (frame < loopStart) {
frame += length;
}
}
}
return frame;
}
Update::Update(J3DFrameCtrl& controller) : m_controller(controller), m_before(controller.getFrame()), m_continuous(true) {
m_travel = controller.getRate();
const f32 next = m_before + m_travel;
const f32 start = controller.getStart();
const f32 end = controller.getEnd();
m_continuous = std::isfinite(m_before) && std::isfinite(next) && end > start;
switch (controller.getAttribute()) {
case J3DFrameCtrl::EMode_NONE:
break;
case J3DFrameCtrl::EMode_RESET:
m_continuous &= next < end;
break;
case J3DFrameCtrl::EMode_LOOP:
m_continuous &= end - start > 1.0f;
m_loopStart = m_travel < 0.0f ? start : controller.getLoop();
m_loopEnd = m_travel < 0.0f ? controller.getLoop() : end;
if (m_loopEnd > m_loopStart && controller.getLoop() >= start && controller.getLoop() <= end) {
m_continuous &= m_before >= start && m_before < end;
} else {
m_loopStart = m_loopEnd = 0.0f;
m_continuous &= next >= start && next < end;
}
break;
case J3DFrameCtrl::EMode_REVERSE:
m_continuous &= next >= start && next < end;
break;
case J3DFrameCtrl::EMode_LOOP_REVERSE:
m_continuous &= next >= start && next < end - 1.0f;
break;
default:
m_continuous = false;
break;
}
}
Update::~Update() {
auto& stored = tables().controllers;
Frames frames = get_frames(&m_controller);
if (!should_capture() || is_presentation_active()) {
reset(&m_controller);
return;
}
const uint64_t tick = sim_tick_seq();
const uint64_t epoch = game_clock::g_frameTiming.presentationEpoch;
const bool same_tick = frames.tick == tick && frames.epoch == epoch && frames.valid;
const f32 current = m_controller.getFrame();
const bool loop = m_loopEnd > m_loopStart;
const bool compatible = !same_tick ||
(frames.loop == loop && (!loop || (frames.loopStart == m_loopStart &&
frames.loopEnd == m_loopEnd && frames.travel * m_travel >= 0.0f)));
const bool continuous = compatible && m_continuous && std::isfinite(current) &&
(!same_tick || (frames.smooth && frames.current == m_before));
const f32 previous = same_tick ? frames.previous : m_before;
Frames captured{continuous ? previous : current, current, tick, epoch, true, continuous};
captured.loop = continuous && loop;
captured.travel = same_tick ? frames.travel + m_travel : m_travel;
captured.loopStart = m_loopStart;
captured.loopEnd = m_loopEnd;
stored[&m_controller] = captured;
}
Sample::Sample(J3DAnmBase* animation) : m_animation(animation), m_frame(animation->getFrame()) {
animation->mFrame = get_frames(animation).read(m_frame);
}
Sample::~Sample() {
m_animation->mFrame = m_frame;
}
void sample_texture(const J3DAnmTextureSRTKey* animation, u16 track, J3DTextureSRTInfo* result) {
const Frames frames = get_frames(animation);
const f32 current = animation->getFrame();
const f32 sampled = frames.read(current);
animation->calcTransform(sampled, track, result);
if (!is_enabled() || !is_presentation_active() || sampled == current) {
return;
}
const auto* table = animation->mAnmTable + track * 3;
result->mTranslationX = sample_texture_translation(table[0].mTranslateInfo, animation->mTransData,
sampled, result->mTranslationX);
result->mTranslationY = sample_texture_translation(table[1].mTranslateInfo, animation->mTransData,
sampled, result->mTranslationY);
}
namespace {
template <typename T>
struct Values {
struct Entry {
T* target;
T captured;
T saved;
};
std::vector<Entry> entries;
bool capture(T* target) {
if (target == nullptr || std::any_of(entries.begin(), entries.end(),
[=](const Entry& entry) {
return entry.target == target;
}))
{
return false;
}
entries.push_back({target, *target, *target});
return true;
}
void apply() {
for (auto& entry : entries) {
entry.saved = *entry.target;
*entry.target = entry.captured;
}
}
void restore() {
for (auto& entry : entries) {
*entry.target = entry.saved;
}
}
};
template <typename Color>
bool same_color(const Color& a, const Color& b) {
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
}
} // namespace
struct ModelBindings::State {
std::tuple<Values<J3DMaterial>,
Values<J3DColorBlockLightOff>, Values<J3DColorBlockAmbientOn>, Values<J3DColorBlockLightOn>,
Values<J3DTexGenBlockPatched>, Values<J3DTexGenBlock4>, Values<J3DTexGenBlockBasic>,
Values<J3DTevBlockPatched>, Values<J3DTevBlock1>, Values<J3DTevBlock2>,
Values<J3DTevBlock4>, Values<J3DTevBlock16>, Values<J3DIndBlockFull>,
Values<J3DPEBlockFogOff>, Values<J3DPEBlockFull>, Values<J3DTexMtx>,
Values<J3DLightInfo>, Values<GXLightObj>, Values<u16>> values;
struct Animation {
J3DMaterial* material;
J3DMaterialAnm tracks;
};
struct Resource {
J3DAnmBase* target;
f32 frame;
Frames frames;
f32 savedFrame;
Frames savedFrames;
};
struct Projection {
J3DTexMtxInfo* target;
ViewProjection recipe;
};
struct Light {
J3DLightInfo* target;
LightView view;
bool rotateDirection;
};
std::vector<Animation> animations;
std::vector<Resource> resources;
std::vector<Projection> projections;
std::vector<Light> lights;
template <typename T>
bool capture(T* target) {
return std::get<Values<T>>(values).capture(target);
}
};
ModelBindings::ModelBindings() : m_state(std::make_unique<State>()) {}
ModelBindings::~ModelBindings() = default;
void ModelBindings::capture(J3DMaterial* material) {
auto& state = *m_state;
if (!state.capture(material)) {
return;
}
auto* color = material->getColorBlock();
switch (color->getType()) {
case 'CLOF': state.capture(static_cast<J3DColorBlockLightOff*>(color)); break;
case 'CLAB': state.capture(static_cast<J3DColorBlockAmbientOn*>(color)); break;
case 'CLON': state.capture(static_cast<J3DColorBlockLightOn*>(color)); break;
}
auto* texgen = material->getTexGenBlock();
switch (texgen->getType()) {
case 'TGPT': state.capture(static_cast<J3DTexGenBlockPatched*>(texgen)); break;
case 'TGB4': state.capture(static_cast<J3DTexGenBlock4*>(texgen)); break;
case 'TGBC': state.capture(static_cast<J3DTexGenBlockBasic*>(texgen)); break;
}
auto* tev = material->getTevBlock();
switch (tev->getType()) {
case 'TVPT': state.capture(static_cast<J3DTevBlockPatched*>(tev)); break;
case 'TVB1': state.capture(static_cast<J3DTevBlock1*>(tev)); break;
case 'TVB2': state.capture(static_cast<J3DTevBlock2*>(tev)); break;
case 'TVB4': state.capture(static_cast<J3DTevBlock4*>(tev)); break;
case 'TV16': state.capture(static_cast<J3DTevBlock16*>(tev)); break;
}
auto* indirect = material->getIndBlock();
if (indirect->getType() == 'IBLF') {
state.capture(static_cast<J3DIndBlockFull*>(indirect));
}
auto* pe = material->getPEBlock();
switch (pe->getType()) {
case 'PEFG': state.capture(static_cast<J3DPEBlockFogOff*>(pe)); break;
case 'PEFL': state.capture(static_cast<J3DPEBlockFull*>(pe)); break;
}
for (int i = 0; i < 8; ++i) {
if (auto* light = color->getLight(i)) {
if (state.capture(light->getLightInfo())) {
if (auto it = tables().lightViews.find(material); i != 1 && it != tables().lightViews.end()) {
state.lights.push_back({light->getLightInfo(), it->second, i >= 2});
}
}
state.capture(&light->mLightObj);
}
if (auto* coord = texgen->getTexCoord(i)) {
state.capture(&coord->mTexMtxReg);
}
if (auto* matrix = texgen->getTexMtx(i); state.capture(matrix)) {
auto* info = &matrix->getTexMtxInfo();
if (auto it = tables().projections.find(info); it != tables().projections.end()) {
state.projections.push_back({info, it->second});
}
}
}
auto* animation = material->getMaterialAnm();
if (animation == nullptr) {
return;
}
auto& tracks = state.animations.emplace_back(State::Animation{material, *animation}).tracks;
for (int i = 0; i < 2; ++i) {
const auto& track = tracks.getMatColorAnm(i);
if (!track.getAnmFlag()) {
continue;
}
capture(track.getAnimation());
GXColor evaluated;
track.calc(&evaluated);
if (!same_color<GXColor>(*material->getMatColor(i), evaluated)) {
tracks.setMatColorAnm(i, nullptr);
}
}
for (int i = 0; i < 8; ++i) {
const auto& track = tracks.getTexNoAnm(i);
if (!track.getAnmFlag()) {
continue;
}
capture(track.getAnimation());
u16 evaluated;
track.calc(&evaluated);
if (material->getTexNo(i) != evaluated) {
tracks.setTexNoAnm(i, nullptr);
}
}
for (int i = 0; i < 8; ++i) {
const auto& track = tracks.getTexMtxAnm(i);
if (!track.getAnmFlag()) {
continue;
}
capture(track.getAnimation());
J3DTextureSRTInfo evaluated;
track.calc(&evaluated);
if (!material->getTexMtx(i)->getTexMtxInfo().mSRT.operator==(evaluated)) {
tracks.setTexMtxAnm(i, nullptr);
}
}
for (int i = 0; i < 3; ++i) {
const auto& track = tracks.getTevColorAnm(i);
if (!track.getAnmFlag()) {
continue;
}
capture(track.getAnimation());
GXColorS10 evaluated;
track.calc(&evaluated);
if (!same_color<GXColorS10>(*material->getTevColor(i), evaluated)) {
tracks.setTevColorAnm(i, nullptr);
}
}
for (int i = 0; i < 4; ++i) {
const auto& track = tracks.getTevKColorAnm(i);
if (!track.getAnmFlag()) {
continue;
}
capture(track.getAnimation());
GXColor evaluated;
track.calc(&evaluated);
if (!same_color<GXColor>(*material->getTevKColor(i), evaluated)) {
tracks.setTevKColorAnm(i, nullptr);
}
}
}
void ModelBindings::capture(J3DAnmBase* resource) {
if (resource == nullptr) {
return;
}
for (const auto& entry : m_state->resources) {
if (entry.target == resource) {
return;
}
}
m_state->resources.push_back({resource, resource->getFrame(), get_frames(resource)});
}
void ModelBindings::apply() {
std::apply([](auto&... values) { (values.apply(), ...); }, m_state->values);
for (auto& entry : m_state->animations) {
entry.material->setMaterialAnm(&entry.tracks);
}
for (auto& entry : m_state->resources) {
entry.savedFrame = entry.target->mFrame;
entry.target->mFrame = entry.frame;
entry.savedFrames = entry.frames;
swap_frames(entry.target, entry.savedFrames);
}
for (const auto& entry : m_state->projections) {
entry.recipe.apply(entry.target);
}
for (const auto& entry : m_state->lights) {
entry.view.apply(entry.target, entry.rotateDirection);
}
}
void ModelBindings::restore() {
for (auto& entry : m_state->resources) {
entry.target->mFrame = entry.savedFrame;
swap_frames(entry.target, entry.savedFrames);
}
std::apply([](auto&... values) { (values.restore(), ...); }, m_state->values);
}
void record_model(J3DModel* model) {
if (!should_capture() || is_presentation_active()) {
return;
}
struct Recording {
J3DModel* model;
ModelBindings bindings;
};
auto recording = std::make_shared<Recording>();
recording->model = model;
J3DModelData* data = model->getModelData();
for (u16 i = 0; i < data->getMaterialNum(); ++i) {
recording->bindings.capture(data->getMaterialNodePointer(i));
}
add_interpolation_callback([](void* work) {
auto& recording = *static_cast<Recording*>(work);
ModelScope scope(recording.bindings);
recording.model->calcMaterial();
recording.model->diff();
}, recording.get(), recording);
}
void set_view_projection(J3DTexMtxInfo* info, f32 scaleS, f32 scaleT, f32 transS, f32 transT) {
ViewProjection recipe{scaleS, scaleT, transS, transT};
recipe.apply(info);
if (should_capture() && !is_presentation_active()) {
tables().projections.insert_or_assign(info, recipe);
}
}
void record_light_view(J3DMaterial* material) {
if (!should_capture() || is_presentation_active()) {
return;
}
LightView view;
if (MTXInverse(j3dSys.getViewMtx(), view.inverse)) {
tables().lightViews.insert_or_assign(material, view);
}
}
} // namespace dusk::interp::material
+104
View File
@@ -0,0 +1,104 @@
#pragma once
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
#include "JSystem/J3DGraphBase/J3DMatBlock.h"
#include <cstdint>
#include <memory>
#include <vector>
class J3DAnmBase;
class J3DFrameCtrl;
class J3DModel;
namespace dusk::interp::material {
class ModelBindings;
struct Frames {
f32 previous = 0.0f;
f32 current = 0.0f;
uint64_t tick = 0;
uint64_t epoch = 0;
bool valid = false;
bool smooth = false;
bool loop = false;
f32 travel = 0.0f;
f32 loopStart = 0.0f;
f32 loopEnd = 0.0f;
f32 read(f32 requested) const;
};
class Update {
public:
explicit Update(J3DFrameCtrl& controller);
~Update();
Update(const Update&) = delete;
Update& operator=(const Update&) = delete;
private:
J3DFrameCtrl& m_controller;
f32 m_before;
bool m_continuous;
f32 m_travel = 0.0f;
f32 m_loopStart = 0.0f;
f32 m_loopEnd = 0.0f;
};
class Sample {
public:
explicit Sample(J3DAnmBase* animation);
~Sample();
Sample(const Sample&) = delete;
Sample& operator=(const Sample&) = delete;
private:
J3DAnmBase* m_animation;
f32 m_frame;
};
class ModelBindings {
public:
ModelBindings();
~ModelBindings();
ModelBindings(const ModelBindings&) = delete;
ModelBindings& operator=(const ModelBindings&) = delete;
void capture(J3DMaterial* material);
void apply();
void restore();
private:
void capture(J3DAnmBase* resource);
struct State;
std::unique_ptr<State> m_state;
};
class ModelScope {
public:
explicit ModelScope(ModelBindings& bindings) : m_bindings(bindings) { m_bindings.apply(); }
~ModelScope() { m_bindings.restore(); }
ModelScope(const ModelScope&) = delete;
ModelScope& operator=(const ModelScope&) = delete;
private:
ModelBindings& m_bindings;
};
void record_model(J3DModel* model);
void set_view_projection(J3DTexMtxInfo* info, f32 scaleS, f32 scaleT, f32 transS, f32 transT);
void record_light_view(J3DMaterial* material);
void sample_texture(const J3DAnmTextureSRTKey* animation, u16 track, J3DTextureSRTInfo* result);
Frames get_frames(const J3DFrameCtrl* controller);
Frames get_frames(const J3DAnmBase* resource);
void reset(const J3DFrameCtrl* controller);
void reset(const J3DAnmBase* resource);
void bind(J3DAnmBase* resource, const J3DFrameCtrl* controller);
void swap_frames(J3DAnmBase* resource, Frames& frames);
void prune();
void clear();
} // namespace dusk::interp::material
+19
View File
@@ -29,6 +29,7 @@
#include "dusk/game_clock.h"
#include "dusk/interp/frame_interpolation.h"
#include "dusk/interp/line.h"
#include "dusk/interp/material.h"
#include "dusk/logging.h"
#include "dusk/version.hpp"
#endif
@@ -147,6 +148,7 @@ int mDoExt_bpkAnm::init(J3DMaterialTable* i_matTable, J3DAnmColor* i_bpk, int i_
int i_attribute, f32 i_rate, s16 i_startF, s16 i_endF) {
JUT_ASSERT(371, (i_anmPlay == FALSE || getFrameCtrl() != NULL || isCurrentSolidHeap()) && i_matTable != NULL && i_bpk != NULL);
IF_DUSK(dusk::interp::material::reset(getFrameCtrl()));
mpAnm = i_bpk;
mpAnm->searchUpdateMaterialID(i_matTable);
@@ -160,6 +162,7 @@ int mDoExt_bpkAnm::init(J3DMaterialTable* i_matTable, J3DAnmColor* i_bpk, int i_
void mDoExt_bpkAnm::entry(J3DMaterialTable* i_matTable, f32 i_frame) {
mpAnm->setFrame(i_frame);
IF_DUSK(dusk::interp::material::bind(mpAnm, getFrameCtrl()));
i_matTable->entryMatColorAnimator(mpAnm);
}
@@ -186,6 +189,7 @@ int mDoExt_btkAnm::init(J3DMaterialTable* i_matTable, J3DAnmTextureSRTKey* i_btk
int i_attribute, f32 i_rate, s16 i_startF, s16 i_endF) {
JUT_ASSERT(468, (i_anmPlay == FALSE || getFrameCtrl() != NULL || isCurrentSolidHeap()) && i_matTable != NULL && i_btk != NULL);
IF_DUSK(dusk::interp::material::reset(getFrameCtrl()));
mpAnm = i_btk;
mpAnm->searchUpdateMaterialID(i_matTable);
@@ -198,6 +202,7 @@ int mDoExt_btkAnm::init(J3DMaterialTable* i_matTable, J3DAnmTextureSRTKey* i_btk
void mDoExt_btkAnm::entry(J3DMaterialTable* i_matTable, f32 i_frame) {
mpAnm->setFrame(i_frame);
IF_DUSK(dusk::interp::material::bind(mpAnm, getFrameCtrl()));
i_matTable->entryTexMtxAnimator(mpAnm);
}
@@ -205,6 +210,7 @@ int mDoExt_brkAnm::init(J3DMaterialTable* i_matTable, J3DAnmTevRegKey* i_brk, in
int i_attribute, f32 i_rate, s16 i_startF, s16 i_endF) {
JUT_ASSERT(516, (i_anmPlay == FALSE || getFrameCtrl() != NULL || isCurrentSolidHeap()) && i_matTable != NULL && i_brk != NULL);
IF_DUSK(dusk::interp::material::reset(getFrameCtrl()));
mpAnm = i_brk;
mpAnm->searchUpdateMaterialID(i_matTable);
@@ -217,6 +223,7 @@ int mDoExt_brkAnm::init(J3DMaterialTable* i_matTable, J3DAnmTevRegKey* i_brk, in
void mDoExt_brkAnm::entry(J3DMaterialTable* i_matTable, f32 i_frame) {
mpAnm->setFrame(i_frame);
IF_DUSK(dusk::interp::material::bind(mpAnm, getFrameCtrl()));
i_matTable->entryTevRegAnimator(mpAnm);
}
@@ -4052,3 +4059,15 @@ static void dummy() {
{ J3DFog temp; temp = temp; J3DFog temp2(temp); }
{ J3DTexMtx temp; temp = temp; J3DTexMtx temp2(temp); }
}
#if TARGET_PC
void mDoExt_btkAnm::entryFrame(f32 frame) {
mpAnm->setFrame(frame);
IF_DUSK(dusk::interp::material::bind(mpAnm, getFrameCtrl()));
}
void mDoExt_brkAnm::entryFrame(f32 frame) {
mpAnm->setFrame(frame);
IF_DUSK(dusk::interp::material::bind(mpAnm, getFrameCtrl()));
}
#endif