1#include <game/mLib/m_3d.hpp>
4m3d::mdl_c::mdlCallback_c::mdlCallback_c() :
5 mNodeCount(0), mpNodeResults(nullptr), mpCallback(nullptr), mpAllocator(nullptr) {}
7m3d::mdl_c::mdlCallback_c::~mdlCallback_c() {}
9void m3d::mdl_c::mdlCallback_c::ExecCallbackA(nw4r::g3d::ChrAnmResult *anmRes, nw4r::g3d::ResMdl resMdl, nw4r::g3d::FuncObjCalcWorld *cw) {
10 u16 nodeID = cw->GetNodeID();
11 nw4r::g3d::ChrAnmResult *result = &mpNodeResults[nodeID];
13 if (mCalcRatio.isActive() && !mCalcRatio.isEnd()) {
14 if (!mCalcRatio.isBlending()) {
17 float slerpParam = mCalcRatio.getSlerpParam();
18 float scaleFrom = mCalcRatio.getScaleFrom();
19 float scaleTo = mCalcRatio.getScaleTo();
21 u32 flags = anmRes->flags;
23 if ((flags & nw4r::g3d::ChrAnmResult::FLAG_SCALE_ONE) == 0) {
24 anmRes->s.x = anmRes->s.x * scaleTo + result->s.x * scaleFrom;
25 anmRes->s.y = anmRes->s.y * scaleTo + result->s.y * scaleFrom;
26 anmRes->s.z = anmRes->s.z * scaleTo + result->s.z * scaleFrom;
28 anmRes->s.x = scaleTo + result->s.x * scaleFrom;
29 anmRes->s.y = scaleTo + result->s.y * scaleFrom;
30 anmRes->s.z = scaleTo + result->s.z * scaleFrom;
34 C_QUATMtx(&p, result->rt.m);
35 if ((flags & nw4r::g3d::ChrAnmResult::FLAG_ROT_ZERO) == 0) {
36 C_QUATMtx(&q, anmRes->rt.m);
44 C_QUATSlerp(&p, &q, &p, slerpParam);
47 cpy.x = anmRes->rt.m[0][3];
48 cpy.y = anmRes->rt.m[1][3];
49 cpy.z = anmRes->rt.m[2][3];
50 PSMTXQuat(anmRes->rt.m, &p);
51 anmRes->rt.m[0][3] = cpy.x;
52 anmRes->rt.m[1][3] = cpy.y;
53 anmRes->rt.m[2][3] = cpy.z;
55 if ((flags & nw4r::g3d::ChrAnmResult::FLAG_TRANS_ZERO) == 0) {
56 anmRes->rt.m[0][3] = cpy.x * scaleTo;
57 anmRes->rt.m[1][3] = cpy.y * scaleTo;
58 anmRes->rt.m[2][3] = cpy.z * scaleTo;
61 anmRes->rt.m[0][3] += result->rt.m[0][3] * scaleFrom;
62 anmRes->rt.m[1][3] += result->rt.m[1][3] * scaleFrom;
63 anmRes->rt.m[2][3] += result->rt.m[2][3] * scaleFrom;
65 anmRes->flags &= ~(nw4r::g3d::ChrAnmResult::FLAG_ROT_RAW_FMT |
66 nw4r::g3d::ChrAnmResult::FLAG_TRANS_ZERO |
67 nw4r::g3d::ChrAnmResult::FLAG_ROT_ZERO |
68 nw4r::g3d::ChrAnmResult::FLAG_SCALE_ONE);
76 if (mpCallback !=
nullptr) {
77 mpCallback->timingA(nodeID, anmRes, resMdl);
81void m3d::mdl_c::mdlCallback_c::ExecCallbackB(nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl, nw4r::g3d::FuncObjCalcWorld *cw) {
82 u16 nodeID = cw->GetNodeID();
83 if (mpCallback !=
nullptr) {
84 mpCallback->timingB(nodeID, manip, resMdl);
87 u32 nodeCount = resMdl.GetResNodeNumEntries();
88 cw->SetNodeID((nodeID + 1) % nodeCount);
91void m3d::mdl_c::mdlCallback_c::ExecCallbackC(nw4r::math::MTX34 *mtx, nw4r::g3d::ResMdl resMdl, nw4r::g3d::FuncObjCalcWorld *cw) {
92 if (mpCallback !=
nullptr) {
93 mpCallback->timingC(mtx, resMdl);
95 mCalcRatio.offUpdate();
98bool m3d::mdl_c::mdlCallback_c::create(nw4r::g3d::ResMdl resMdl, mAllocator_c *allocator,
size_t *pSize) {
99 if (allocator ==
nullptr) {
100 allocator = internal::l_allocator_p;
104 if (pSize ==
nullptr) {
108 mNodeCount = resMdl.GetResNodeNumEntries();
109 size_t resultSize = mNodeCount *
sizeof(nw4r::g3d::ChrAnmResult);
111 mpNodeResults = (nw4r::g3d::ChrAnmResult *) MEMAllocFromAllocator(allocator, resultSize);
112 if (mpNodeResults ==
nullptr) {
116 *pSize = nw4r::ut::RoundUp(resultSize + nw4r::ut::RoundUp(*pSize, 4), 4);
118 nw4r::g3d::ChrAnmResult *curr = mpNodeResults;
119 for (
int i = 0; i < mNodeCount; i++) {
123 PSMTXIdentity(curr->rt.m);
127 mpAllocator = allocator;
131void m3d::mdl_c::mdlCallback_c::remove() {
133 if (mpNodeResults !=
nullptr) {
134 mpAllocator->free(mpNodeResults);
136 mpNodeResults =
nullptr;
137 mpAllocator =
nullptr;
140void m3d::mdl_c::mdlCallback_c::setBlendFrame(
float blendFrame) {
141 mCalcRatio.set(blendFrame);
144void m3d::mdl_c::mdlCallback_c::calcBlend() {
145 if (!mCalcRatio.isEnd()) {
150m3d::mdl_c::mdl_c() {}
151m3d::mdl_c::~mdl_c() {}
153bool m3d::mdl_c::create(nw4r::g3d::ResMdl resMdl, mAllocator_c *allocator, ulong bufferOption,
int viewCount,
size_t *pSize) {
154 if (allocator ==
nullptr) {
155 allocator = internal::l_allocator_p;
158 size_t *pMdlSize =
nullptr;
159 size_t *pMdlCallbackSize =
nullptr;
161 size_t mdlCallbackSize;
162 if (pSize !=
nullptr) {
164 pMdlCallbackSize = &mdlCallbackSize;
167 bool createMdlRes = smdl_c::create(resMdl, allocator, bufferOption, viewCount, pMdlSize);
172 bool createCbRes = mCallback.create(resMdl, allocator, pMdlCallbackSize);
178 if (pSize !=
nullptr) {
179 *pSize = mdlSize + mdlCallbackSize;
182 nw4r::g3d::ScnMdlSimple *scnMdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScn);
183 scnMdl->SetScnMdlCallback((nw4r::g3d::ICalcWorldCallback *) &mCallback);
184 scnMdl->EnableScnMdlCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_ALL);
186 setCallback(
nullptr);
190void m3d::mdl_c::remove() {
192 m3d::smdl_c::remove();
195void m3d::mdl_c::setAnm(m3d::banm_c &anm) {
199void m3d::mdl_c::play() {
201 mCallback.calcBlend();
204void m3d::mdl_c::setAnm(m3d::banm_c &anm,
float blendFrame) {
205 if (anm.getType() == m3d::banm_c::TYPE_ANM_CHR) {
206 mCallback.setBlendFrame(blendFrame);
212void m3d::mdl_c::setCallback(m3d::mdl_c::callback_c *callback) {
213 mCallback.mpCallback = callback;