1#include <game/mLib/m_3d.hpp>
2#include <lib/nw4r/ut/inlines.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->mNodeID;
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->
mFlags;
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;
34 C_QUATMtx(&p, &result->
mMtx.mtx);
36 C_QUATMtx(&q, &anmRes->
mMtx.mtx);
44 C_QUATSlerp(&p, &q, &p, slerpParam);
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;
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;
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;
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->mNodeID;
83 if (mpCallback !=
nullptr) {
84 mpCallback->timingB(nodeID, manip, resMdl);
87 u32 nodeCount = resMdl.GetResNodeNumEntries();
88 cw->mNodeID = (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) {
118 nw4r::g3d::ChrAnmResult *curr = mpNodeResults;
119 for (
int i = 0; i < mNodeCount; i++) {
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->mpCallback = &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;
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.
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.