NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
mdl.cpp
1#include <game/mLib/m_3d.hpp>
2#include <lib/nw4r/ut/inlines.hpp>
3
4m3d::mdl_c::mdlCallback_c::mdlCallback_c() :
5 mNodeCount(0), mpNodeResults(nullptr), mpCallback(nullptr), mpAllocator(nullptr) {}
6
7m3d::mdl_c::mdlCallback_c::~mdlCallback_c() {}
8
9void m3d::mdl_c::mdlCallback_c::ExecCallbackA(nw4r::g3d::ChrAnmResult *anmRes, nw4r::g3d::ResMdl resMdl, nw4r::g3d::FuncObjCalcWorld *cw) {
10 u16 nodeID = cw->mNodeID;
11 nw4r::g3d::ChrAnmResult *result = &mpNodeResults[nodeID];
12
13 if (mCalcRatio.isActive() && !mCalcRatio.isEnd()) {
14 if (!mCalcRatio.isBlending()) {
15 *anmRes = *result;
16 } else {
17 float slerpParam = mCalcRatio.getSlerpParam();
18 float scaleFrom = mCalcRatio.getScaleFrom();
19 float scaleTo = mCalcRatio.getScaleTo();
20
21 u32 flags = anmRes->mFlags;
22
23 if ((flags & nw4r::g3d::ChrAnmResult::FLAG_SCALE_ONE) == 0) {
24 anmRes->mScale.x = anmRes->mScale.x * scaleTo + result->mScale.x * scaleFrom;
25 anmRes->mScale.y = anmRes->mScale.y * scaleTo + result->mScale.y * scaleFrom;
26 anmRes->mScale.z = anmRes->mScale.z * scaleTo + result->mScale.z * scaleFrom;
27 } else {
28 anmRes->mScale.x = scaleTo + result->mScale.x * scaleFrom;
29 anmRes->mScale.y = scaleTo + result->mScale.y * scaleFrom;
30 anmRes->mScale.z = scaleTo + result->mScale.z * scaleFrom;
31 }
32
33 QUAT p, q;
34 C_QUATMtx(&p, &result->mMtx.mtx);
36 C_QUATMtx(&q, &anmRes->mMtx.mtx);
37 } else {
38 q.x = 0;
39 q.y = 0;
40 q.z = 0;
41 q.w = 1;
42 }
43
44 C_QUATSlerp(&p, &q, &p, slerpParam);
45
46 nw4r::math::VEC3 cpy;
47 cpy.x = anmRes->mMtx.mData[0][3];
48 cpy.y = anmRes->mMtx.mData[1][3];
49 cpy.z = anmRes->mMtx.mData[2][3];
50 PSMTXQuat(&anmRes->mMtx.mtx, &p);
51 anmRes->mMtx.mData[0][3] = cpy.x;
52 anmRes->mMtx.mData[1][3] = cpy.y;
53 anmRes->mMtx.mData[2][3] = cpy.z;
54
56 anmRes->mMtx.mData[0][3] = cpy.x * scaleTo;
57 anmRes->mMtx.mData[1][3] = cpy.y * scaleTo;
58 anmRes->mMtx.mData[2][3] = cpy.z * scaleTo;
59 }
60
61 anmRes->mMtx.mData[0][3] += result->mMtx.mData[0][3] * scaleFrom;
62 anmRes->mMtx.mData[1][3] += result->mMtx.mData[1][3] * scaleFrom;
63 anmRes->mMtx.mData[2][3] += result->mMtx.mData[2][3] * scaleFrom;
64
69
70 *result = *anmRes;
71 }
72 } else {
73 *result = *anmRes;
74 }
75
76 if (mpCallback != nullptr) {
77 mpCallback->timingA(nodeID, anmRes, resMdl);
78 }
79}
80
81void m3d::mdl_c::mdlCallback_c::ExecCallbackB(nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl resMdl, nw4r::g3d::FuncObjCalcWorld *cw) {
82 u16 nodeID = cw->mNodeID;
83 if (mpCallback != nullptr) {
84 mpCallback->timingB(nodeID, manip, resMdl);
85 }
86
87 u32 nodeCount = resMdl.GetResNodeNumEntries();
88 cw->mNodeID = (nodeID + 1) % nodeCount;
89}
90
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);
94 }
95 mCalcRatio.offUpdate();
96}
97
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;
101 }
102
103 size_t size = 0;
104 if (pSize == nullptr) {
105 pSize = &size;
106 }
107
108 mNodeCount = resMdl.GetResNodeNumEntries();
109 size_t resultSize = mNodeCount * sizeof(nw4r::g3d::ChrAnmResult);
110
111 mpNodeResults = (nw4r::g3d::ChrAnmResult *) MEMAllocFromAllocator(allocator, resultSize);
112 if (mpNodeResults == nullptr) {
113 return false;
114 }
115
116 *pSize = nw4r::ut::RoundUp(resultSize + nw4r::ut::RoundUp(*pSize, 4), 4);
117
118 nw4r::g3d::ChrAnmResult *curr = mpNodeResults;
119 for (int i = 0; i < mNodeCount; i++) {
120 curr->mScale.x = 1.0f;
121 curr->mScale.y = 1.0f;
122 curr->mScale.z = 1.0f;
123 PSMTXIdentity(&curr->mMtx.mtx);
124 curr++;
125 }
126
127 mpAllocator = allocator;
128 return true;
129}
130
131void m3d::mdl_c::mdlCallback_c::remove() {
132 mCalcRatio.remove();
133 if (mpNodeResults != nullptr) {
134 mpAllocator->free(mpNodeResults);
135 }
136 mpNodeResults = nullptr;
137 mpAllocator = nullptr;
138}
139
140void m3d::mdl_c::mdlCallback_c::setBlendFrame(float blendFrame) {
141 mCalcRatio.set(blendFrame);
142}
143
144void m3d::mdl_c::mdlCallback_c::calcBlend() {
145 if (!mCalcRatio.isEnd()) {
146 mCalcRatio.calc();
147 }
148}
149
150m3d::mdl_c::mdl_c() {}
151m3d::mdl_c::~mdl_c() {}
152
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;
156 }
157
158 size_t *pMdlSize = nullptr;
159 size_t *pMdlCallbackSize = nullptr;
160 size_t mdlSize;
161 size_t mdlCallbackSize;
162 if (pSize != nullptr) {
163 pMdlSize = &mdlSize;
164 pMdlCallbackSize = &mdlCallbackSize;
165 }
166
167 bool createMdlRes = smdl_c::create(resMdl, allocator, bufferOption, viewCount, pMdlSize);
168 if (!createMdlRes) {
169 return false;
170 }
171
172 bool createCbRes = mCallback.create(resMdl, allocator, pMdlCallbackSize);
173 if (!createCbRes) {
174 remove();
175 return false;
176 }
177
178 if (pSize != nullptr) {
179 *pSize = mdlSize + mdlCallbackSize;
180 }
181
182 nw4r::g3d::ScnMdlSimple *scnMdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScn);
183 scnMdl->mpCallback = &mCallback;
184 scnMdl->EnableScnMdlCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_ALL);
185
186 setCallback(nullptr);
187 return true;
188}
189
190void m3d::mdl_c::remove() {
191 mCallback.remove();
192 m3d::smdl_c::remove();
193}
194
195void m3d::mdl_c::setAnm(m3d::banm_c &anm) {
196 setAnm(anm, 0.0f);
197}
198
199void m3d::mdl_c::play() {
200 m3d::bmdl_c::play();
201 mCallback.calcBlend();
202}
203
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);
207 }
208
209 bmdl_c::setAnm(anm);
210}
211
212void m3d::mdl_c::setCallback(m3d::mdl_c::callback_c *callback) {
213 mCallback.mpCallback = callback;
214}
void PSMTXIdentity(Mtx *mtx)
Sets the given matrix to the identity matrix.
T RoundUp(T x, u32 base)
Rounds x up to a multiple of base.
Definition inlines.hpp:21
u32 mFlags
The attributes held by the character animation result data. See Flag.
nw4r::math::MTX34 mMtx
The matrix for rotation and translation.
@ FLAG_RAW_ROTATE_VALID
An appropriate value is stored in ChrAnmResult::mRotation.
@ FLAG_TRANS_ZERO
The translation is always 0.
@ FLAG_SCALE_ONE
The scale is always 1.
@ FLAG_ROTATE_ZERO
The rotation is always 0.
nw4r::math::VEC3 mScale
The result scale.