mirror of
https://github.com/zeldaret/ss
synced 2026-06-03 18:36:16 -04:00
m3d (#13)
* Initial M3d Pass * `m_bmdl` and `m_bline` left --------- Co-authored-by: elijah-thomas774 <elijahthomas774@gmail.com> Co-authored-by: Elijah Thomas <42302100+elijah-thomas774@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
#include <egg/gfx/eggDrawGX.h>
|
||||
#include <egg/gfx/eggGfxEngine.h>
|
||||
#include <egg/gfx/eggScreen.h>
|
||||
#include <egg/gfx/eggStateGX.h>
|
||||
|
||||
#include <nw4r/g3d/g3d_camera.h>
|
||||
#include <nw4r/g3d/g3d_init.h>
|
||||
#include <nw4r/g3d/g3d_resmat.h>
|
||||
#include <nw4r/g3d/g3d_resmdl.h>
|
||||
#include <nw4r/g3d/g3d_state.h>
|
||||
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m_heap.h>
|
||||
#include <m/m_video.h>
|
||||
|
||||
#include <rvl/GX.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
namespace internal {
|
||||
|
||||
mAllocator_c *l_allocator_p;
|
||||
nw4r::g3d::ScnRoot *l_scnRoot_p;
|
||||
u32 l_numLightMgr;
|
||||
EGG::LightManager **l_lightMgr_pp;
|
||||
u32 l_numFogMgr;
|
||||
EGG::FogManager **l_fogMgr_pp;
|
||||
size_t l_alignment;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
bool create(EGG::Heap *pHeap, u32 maxNumChildren, u32 maxNumScnObj, u32 numLightObj, u32 numLightSet) {
|
||||
internal::l_allocator_p = new (pHeap) mAllocator_c();
|
||||
|
||||
if (!internal::l_allocator_p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
internal::l_allocator_p->attach(pHeap, 0x20);
|
||||
nw4r::g3d::G3dInit(true);
|
||||
nw4r::g3d::G3DState::SetRenderModeObj(*mVideo::m_video->pRenderMode);
|
||||
u32 allocedSize;
|
||||
internal::l_scnRoot_p = nw4r::g3d::ScnRoot::Construct(internal::l_allocator_p, &allocedSize, maxNumChildren,
|
||||
maxNumScnObj, numLightObj, numLightSet);
|
||||
if (internal::l_scnRoot_p == nullptr) {
|
||||
delete internal::l_allocator_p;
|
||||
internal::l_allocator_p = nullptr;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool create(EGG::Heap *pHeap, GXPixelFmt pxlFmt, GXColor clearColor, u32 maxNumChildren, u32 maxNumScnObj,
|
||||
u32 numLightObj, u32 numLightSet, u32 numLightMgr, u32 numFogMgr) {
|
||||
if (internal::l_lightMgr_pp && internal::l_fogMgr_pp) {
|
||||
return false;
|
||||
}
|
||||
EGG::GfxEngine::Configuration config = EGG::GfxEngine::Configuration();
|
||||
|
||||
u16 temp1[2] = {config.field_0x14, config.field_0x16};
|
||||
u16 temp2[2] = {config.efbHeight, config.efbHeight};
|
||||
|
||||
EGG::StateGX::initialize(config.efbWidth, config.efbHeight, clearColor, pxlFmt);
|
||||
EGG::Screen::Initialize(temp1, temp2, nullptr);
|
||||
EGG::Screen::SetTVModeDefault();
|
||||
EGG::DrawGX::Initialize(pHeap);
|
||||
|
||||
EGG::LightTexture::initialize(0x20, pHeap);
|
||||
|
||||
internal::l_lightMgr_pp = new (pHeap) EGG::LightManager *[numLightMgr];
|
||||
if (internal::l_lightMgr_pp) {
|
||||
internal::l_numLightMgr = numLightMgr;
|
||||
internal::l_fogMgr_pp = new (pHeap) EGG::FogManager *[numFogMgr];
|
||||
if (internal::l_fogMgr_pp) {
|
||||
internal::l_numFogMgr = numFogMgr;
|
||||
memset(internal::l_lightMgr_pp, 0, numLightMgr * 4);
|
||||
memset(internal::l_fogMgr_pp, 0, numFogMgr * 4);
|
||||
|
||||
if (create(pHeap, maxNumChildren, maxNumScnObj, numLightObj, numLightSet)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creation failed :(
|
||||
delete[] internal::l_lightMgr_pp;
|
||||
internal::l_lightMgr_pp = nullptr;
|
||||
delete[] internal::l_fogMgr_pp;
|
||||
internal::l_fogMgr_pp = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool createLightMgr(EGG::Heap *pHeap, u16 p2, u16 p3, u8 p4, bool bCreateFogMgr, int idx) {
|
||||
using namespace internal;
|
||||
|
||||
if (!l_lightMgr_pp || (idx < 0 || idx >= l_numLightMgr || idx >= l_numFogMgr) ||
|
||||
(l_lightMgr_pp[idx] || l_fogMgr_pp[idx])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EGG::Heap *prevHeap = mHeap::setCurrentHeap(pHeap);
|
||||
EGG::LightManager *lightMgr = new (pHeap) EGG::LightManager(p2, p3, p4);
|
||||
mHeap::setCurrentHeap(prevHeap);
|
||||
|
||||
if (lightMgr) {
|
||||
if (!bCreateFogMgr || createFogMgr(pHeap, 0x20, idx)) {
|
||||
l_lightMgr_pp[idx] = lightMgr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
delete lightMgr;
|
||||
return false;
|
||||
|
||||
u8 input;
|
||||
u8 *output;
|
||||
switch (input % 8) {
|
||||
do {
|
||||
case 0:
|
||||
*output++ = input;
|
||||
case 1:
|
||||
*output++ = input;
|
||||
case 2:
|
||||
*output++ = input;
|
||||
} while (true);
|
||||
}
|
||||
}
|
||||
|
||||
bool createFogMgr(EGG::Heap *pHeap, int numFog, int idx) {
|
||||
using namespace internal;
|
||||
|
||||
if (idx < 0 || idx >= l_numFogMgr || l_fogMgr_pp[idx]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EGG::FogManager *fogMgr;
|
||||
{
|
||||
mHeap heap(pHeap);
|
||||
fogMgr = new (pHeap) EGG::FogManager(numFog);
|
||||
}
|
||||
|
||||
if (!fogMgr) {
|
||||
return false;
|
||||
}
|
||||
l_fogMgr_pp[idx] = fogMgr;
|
||||
return true;
|
||||
}
|
||||
|
||||
nw4r::g3d::ScnRoot *getScnRoot() {
|
||||
return internal::l_scnRoot_p;
|
||||
}
|
||||
|
||||
nw4r::g3d::Camera getCamera(int id) {
|
||||
return internal::l_scnRoot_p->GetCamera(id);
|
||||
}
|
||||
|
||||
nw4r::g3d::Camera getCurrentCamera() {
|
||||
return internal::l_scnRoot_p->GetCurrentCamera();
|
||||
}
|
||||
|
||||
int getCurrentCameraID() {
|
||||
return internal::l_scnRoot_p->GetCurrentCameraID();
|
||||
}
|
||||
|
||||
void setCurrentCamera(int id) {
|
||||
internal::l_scnRoot_p->SetCurrentCamera(id);
|
||||
}
|
||||
|
||||
nw4r::g3d::LightSetting *getLightSettingP() {
|
||||
return internal::l_scnRoot_p->getLightSetting();
|
||||
}
|
||||
|
||||
EGG::LightManager *getLightMgr(int idx) {
|
||||
return internal::l_lightMgr_pp[idx];
|
||||
}
|
||||
|
||||
EGG::FogManager *getFogMgr(int idx) {
|
||||
return internal::l_fogMgr_pp[idx];
|
||||
}
|
||||
|
||||
void drawDone(int idx) {
|
||||
if (internal::l_lightMgr_pp && internal::l_lightMgr_pp[idx]) {
|
||||
internal::l_lightMgr_pp[idx]->DoneDraw();
|
||||
}
|
||||
if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) {
|
||||
internal::l_fogMgr_pp[idx]->mFlag &= 0xFB;
|
||||
}
|
||||
}
|
||||
|
||||
void drawLightMapTexture(int idx) {
|
||||
using namespace internal;
|
||||
|
||||
if (!l_lightMgr_pp) {
|
||||
return;
|
||||
}
|
||||
if (!l_lightMgr_pp[idx]) {
|
||||
return;
|
||||
}
|
||||
|
||||
l_lightMgr_pp[idx]->GetTextureMgr()->drawAndCaptureTexture(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void calcWorld(int idx) {
|
||||
if (internal::l_lightMgr_pp && internal::l_lightMgr_pp[idx]) {
|
||||
internal::l_lightMgr_pp[idx]->Calc(internal::l_scnRoot_p);
|
||||
}
|
||||
if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) {
|
||||
internal::l_fogMgr_pp[idx]->Calc();
|
||||
}
|
||||
internal::l_scnRoot_p->CalcWorld();
|
||||
}
|
||||
|
||||
void calcMaterial() {
|
||||
internal::l_scnRoot_p->CalcMaterial();
|
||||
}
|
||||
|
||||
void calcView(int idx) {
|
||||
if (internal::l_lightMgr_pp && internal::l_lightMgr_pp[idx]) {
|
||||
nw4r::math::MTX34 camMtx;
|
||||
getCurrentCamera().GetCameraMtx(&camMtx);
|
||||
internal::l_lightMgr_pp[idx]->CalcView(camMtx, getCurrentCameraID(), internal::l_scnRoot_p);
|
||||
}
|
||||
if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) {
|
||||
internal::l_fogMgr_pp[idx]->CopyToG3D(internal::l_scnRoot_p);
|
||||
}
|
||||
|
||||
internal::l_scnRoot_p->CalcView();
|
||||
internal::l_scnRoot_p->GatherDrawScnObj();
|
||||
internal::l_scnRoot_p->ZSort();
|
||||
}
|
||||
|
||||
void drawOpa() {
|
||||
internal::l_scnRoot_p->DrawOpa();
|
||||
}
|
||||
|
||||
void drawXlu() {
|
||||
internal::l_scnRoot_p->DrawXlu();
|
||||
}
|
||||
|
||||
bool pushBack(nw4r::g3d::ScnObj *obj) {
|
||||
return internal::l_scnRoot_p->PushBack(obj);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
internal::l_scnRoot_p->Clear();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
nw4r::g3d::G3dReset();
|
||||
if (internal::l_lightMgr_pp || internal::l_fogMgr_pp) {
|
||||
EGG::StateGX::resetGXCache();
|
||||
}
|
||||
}
|
||||
|
||||
int getMatID(nw4r::g3d::ResMdl mdl, const char *name) {
|
||||
if (mdl.IsValid()) {
|
||||
nw4r::g3d::ResMat mat = mdl.GetResMat(name);
|
||||
if (mat.IsValid()) {
|
||||
return mat.ref().id;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getNodeID(nw4r::g3d::ResMdl mdl, const char *name) {
|
||||
if (mdl.IsValid()) {
|
||||
nw4r::g3d::ResNode node = mdl.GetResNode(name);
|
||||
if (node.IsValid()) {
|
||||
return node.GetID();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void resetMaterial() {
|
||||
GXSetNumIndStages(0);
|
||||
for (int i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) {
|
||||
GXSetTevDirect((GXTevStageID)i);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,82 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_anmchr.h>
|
||||
#include <nw4r/g3d/g3d_anmchr.h>
|
||||
#include <nw4r/g3d/g3d_resanmchr.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
anmChr_c::~anmChr_c() {}
|
||||
int anmChr_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR;
|
||||
}
|
||||
|
||||
bool anmChr_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmChr anm, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
nw4r::g3d::AnmObjChrRes::Construct(nullptr, pSize, anm, mdl, false);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjChrRes::Construct(&mAllocator, &size, anm, mdl, false);
|
||||
if (!mpAnmObj->Bind(mdl)) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
setFrmCtrlDefault(anm, PLAY_MODE_4);
|
||||
return true;
|
||||
}
|
||||
|
||||
void anmChr_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmChr anm, playMode_e mode) {
|
||||
mdl.removeAnm((nw4r::g3d::ScnMdlSimple::AnmObjType)getType());
|
||||
setAnmAfter(mdl, anm, mode);
|
||||
}
|
||||
|
||||
void anmChr_c::setAnmAfter(bmdl_c &mdl, nw4r::g3d::ResAnmChr anm, playMode_e mode) {
|
||||
nw4r::g3d::AnmObjChrNode *node;
|
||||
nw4r::g3d::G3dObj *parent = mpAnmObj->GetParent();
|
||||
f32 weight;
|
||||
int idx;
|
||||
if (parent != nullptr) {
|
||||
node = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrNode>(parent);
|
||||
int size = node->Size();
|
||||
idx = 0;
|
||||
for (int i = 0; i < size; i++, idx++) {
|
||||
if (node->GetNode(i) == mpAnmObj) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
weight = node->GetWeight(idx);
|
||||
node->Detach(idx);
|
||||
}
|
||||
mpAnmObj->Release();
|
||||
mpAnmObj->Destroy();
|
||||
mpFrameHeap->free(3);
|
||||
u32 tmp;
|
||||
mpAnmObj = nw4r::g3d::AnmObjChrRes::Construct(&mAllocator, &tmp, anm, mdl.getResMdl(), false);
|
||||
mpAnmObj->Bind(mdl.getResMdl());
|
||||
setFrmCtrlDefault(anm, mode);
|
||||
|
||||
if (parent != nullptr) {
|
||||
nw4r::g3d::AnmObjChrRes *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrRes>(mpAnmObj);
|
||||
node->SetWeight(idx, weight);
|
||||
node->Attach(idx, o);
|
||||
}
|
||||
}
|
||||
|
||||
void anmChr_c::setFrmCtrlDefault(nw4r::g3d::ResAnmChr &anm, m3d::playMode_e mode) {
|
||||
if (mode == PLAY_MODE_4) {
|
||||
mode = anm.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
|
||||
}
|
||||
set(anm.GetNumFrame(), mode, 1.0f, -1.0f);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,56 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_anmchrblend.h>
|
||||
#include <nw4r/g3d/g3d_anmchr.h>
|
||||
#include <nw4r/g3d/g3d_resanmchr.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
anmChrBlend_c::~anmChrBlend_c() {}
|
||||
|
||||
int anmChrBlend_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR;
|
||||
}
|
||||
|
||||
bool anmChrBlend_c::create(nw4r::g3d::ResMdl mdl, int num, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
nw4r::g3d::AnmObjChrBlend::Construct(nullptr, pSize, mdl, num);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjChrBlend::Construct(&mAllocator, &size, mdl, num);
|
||||
return true;
|
||||
}
|
||||
|
||||
void anmChrBlend_c::attach(int idx, nw4r::g3d::AnmObjChrRes *anm, f32 weight) {
|
||||
nw4r::g3d::AnmObjChrBlend *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj);
|
||||
obj->SetWeight(idx, weight);
|
||||
obj->Attach(idx, anm);
|
||||
}
|
||||
|
||||
void anmChrBlend_c::attach(int idx, anmChr_c *anm, f32 weight) {
|
||||
nw4r::g3d::AnmObjChrRes *res = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrRes>(anm->getAnimObj());
|
||||
attach(idx, res, weight);
|
||||
}
|
||||
|
||||
void anmChrBlend_c::detach(int idx) {
|
||||
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj)->Detach(idx);
|
||||
}
|
||||
|
||||
void anmChrBlend_c::setWeight(int idx, f32 weight) {
|
||||
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj)->SetWeight(idx, weight);
|
||||
}
|
||||
|
||||
f32 anmChrBlend_c::getWeight(int idx) const {
|
||||
return nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj)->GetWeight(idx);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,203 @@
|
||||
#include <egg/core/eggFrmHeap.h>
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_anmmatclr.h>
|
||||
#include <m/m_heap.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
anmMatClr_c::child_c::~child_c() {}
|
||||
|
||||
int anmMatClr_c::child_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_MATCLR;
|
||||
}
|
||||
|
||||
u32 anmMatClr_c::child_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, bool b) {
|
||||
u32 size = 0;
|
||||
nw4r::g3d::AnmObjMatClrRes::Construct(nullptr, &size, clr, mdl, false);
|
||||
if (b) {
|
||||
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool anmMatClr_c::child_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
*pSize = child_c::heapCost(mdl, clr, false);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjMatClrRes::Construct(&mAllocator, nullptr, clr, mdl, false);
|
||||
|
||||
if (!mpAnmObj->Bind(mdl)) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
setFrmCtrlDefault(clr, PLAY_MODE_4);
|
||||
return true;
|
||||
}
|
||||
|
||||
void anmMatClr_c::child_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmClr clr, m3d::playMode_e mode) {
|
||||
releaseAnm();
|
||||
mpAnmObj = nw4r::g3d::AnmObjMatClrRes::Construct(&mAllocator, nullptr, clr, mdl.getResMdl(), false);
|
||||
mpAnmObj->Bind(mdl.getResMdl());
|
||||
setFrmCtrlDefault(clr, mode);
|
||||
}
|
||||
|
||||
void anmMatClr_c::child_c::releaseAnm() {
|
||||
if (mpAnmObj != nullptr) {
|
||||
mpAnmObj->Release();
|
||||
mpFrameHeap->free(3);
|
||||
mpAnmObj = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void anmMatClr_c::child_c::setFrmCtrlDefault(nw4r::g3d::ResAnmClr &clr, playMode_e mode) {
|
||||
if (mode == PLAY_MODE_4) {
|
||||
mode = clr.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
|
||||
}
|
||||
set(clr.GetNumFrame(), mode, 1.0f, -1.0f);
|
||||
}
|
||||
|
||||
u32 anmMatClr_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, s32 num, bool b) {
|
||||
u32 size = 0;
|
||||
nw4r::g3d::AnmObjMatClrOverride::Construct(nullptr, &size, mdl, num);
|
||||
size += ROUND_UP(num * sizeof(child_c), 0x20);
|
||||
u32 childCost = child_c::heapCost(mdl, clr, true);
|
||||
size += num * ROUND_UP(childCost, 0x20);
|
||||
|
||||
if (b) {
|
||||
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool anmMatClr_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, mAllocator_c *alloc, u32 *pSize, s32 num) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size = 0;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
*pSize = heapCost(mdl, clr, num, false);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjMatClrOverride::Construct(&mAllocator, nullptr, mdl, num);
|
||||
|
||||
// TODO inline?
|
||||
mpChildren = (child_c *)MEMAllocFromAllocator(&mAllocator, ROUND_UP(num * sizeof(child_c), 0x20));
|
||||
|
||||
nw4r::g3d::AnmObjMatClrOverride *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
|
||||
child_c *child = mpChildren;
|
||||
for (int i = 0; i < num; i++) {
|
||||
new (child) child_c();
|
||||
if (!child->create(mdl, clr, &mAllocator, nullptr)) {
|
||||
mHeap::destroyFrmHeap(mpFrameHeap);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
obj->Attach(i, nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrRes>(child->getAnimObj()));
|
||||
} else {
|
||||
child->releaseAnm();
|
||||
}
|
||||
child++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
anmMatClr_c::~anmMatClr_c() {
|
||||
anmMatClr_c::remove();
|
||||
}
|
||||
|
||||
int anmMatClr_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_MATCLR;
|
||||
}
|
||||
|
||||
void anmMatClr_c::remove() {
|
||||
nw4r::g3d::AnmObjMatClrOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
|
||||
if (o != nullptr && mpChildren != 0) {
|
||||
int size = o->Size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
mpChildren[i].remove();
|
||||
}
|
||||
mpChildren = nullptr;
|
||||
}
|
||||
banm_c::remove();
|
||||
}
|
||||
|
||||
void anmMatClr_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmClr clr, s32 idx, playMode_e mode) {
|
||||
nw4r::g3d::AnmObjMatClrOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
|
||||
o->Detach(idx);
|
||||
mpChildren[idx].setAnm(mdl, clr, mode);
|
||||
|
||||
nw4r::g3d::AnmObjMatClrRes *res =
|
||||
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrRes>(mpChildren[idx].getAnimObj());
|
||||
o->Attach(idx, res);
|
||||
}
|
||||
|
||||
void anmMatClr_c::play() {
|
||||
nw4r::g3d::AnmObjMatClrOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
|
||||
int size = o->Size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
play(i);
|
||||
}
|
||||
}
|
||||
|
||||
void anmMatClr_c::play(s32 idx) {
|
||||
if (mpChildren[idx].IsBound()) {
|
||||
mpChildren[idx].play();
|
||||
}
|
||||
}
|
||||
|
||||
f32 anmMatClr_c::getFrame(s32 idx) const {
|
||||
return mpChildren[idx].getFrame();
|
||||
}
|
||||
|
||||
void anmMatClr_c::setFrame(f32 f, s32 idx) {
|
||||
mpChildren[idx].setFrameOnly(f);
|
||||
}
|
||||
|
||||
f32 anmMatClr_c::getRate(s32 idx) const {
|
||||
return mpChildren[idx].getRate();
|
||||
}
|
||||
|
||||
void anmMatClr_c::setRate(f32 f, s32 idx) {
|
||||
mpChildren[idx].setRate(f);
|
||||
}
|
||||
|
||||
bool anmMatClr_c::isStop(s32 idx) const {
|
||||
return mpChildren[idx].isStop();
|
||||
}
|
||||
|
||||
bool anmMatClr_c::checkFrame(f32 f, s32 idx) const {
|
||||
return mpChildren[idx].checkFrame(f);
|
||||
}
|
||||
|
||||
void anmMatClr_c::setPlayMode(playMode_e mode, s32 idx) {
|
||||
mpChildren[idx].setPlayState(mode);
|
||||
}
|
||||
|
||||
f32 anmMatClr_c::getFrameMax(s32 idx) const {
|
||||
return mpChildren[idx].getEndFrame();
|
||||
}
|
||||
|
||||
f32 anmMatClr_c::getFrameStart(s32 idx) const {
|
||||
return mpChildren[idx].getStartFrame();
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,77 @@
|
||||
#include <m/m3d/m_anmmdl.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
mdlAnmChr::~mdlAnmChr() {}
|
||||
|
||||
void mdlAnmChr::play() {
|
||||
mMdl.play();
|
||||
}
|
||||
|
||||
void mdlAnmChr::setFrame(f32 f) {
|
||||
mAnm.setFrameOnly(f);
|
||||
}
|
||||
|
||||
void mdlAnmChr::setAnm(const char *name, playMode_e mode) {
|
||||
setAnm(name, mode, 0.0f);
|
||||
}
|
||||
|
||||
void mdlAnmChr::setRate(f32 rate) {
|
||||
mAnm.setRate(rate);
|
||||
}
|
||||
|
||||
bool mdlAnmChr::create(void *mdlFile, void *anmFile, const char *mdlName, const char *anmName, mAllocator_c *alloc,
|
||||
u32 bufferOption, int nView, u32 *pSize) {
|
||||
return create(mdlFile, anmFile, mdlName, anmName, nullptr, alloc, bufferOption, nView, pSize);
|
||||
}
|
||||
|
||||
bool mdlAnmChr::create2(void *mdlFile, void *anmFile, const char *mdlName, const char *anmName, mAllocator_c *alloc,
|
||||
u32 bufferOption, int nView, u32 *pSize) {
|
||||
return create(mdlFile, anmFile, mdlName, anmName, alloc, bufferOption, nView, pSize);
|
||||
}
|
||||
|
||||
bool mdlAnmChr::create(void *mdlFile, void *anmFile, const char *mdlName, const char *anmName,
|
||||
mdl_c::mdlCallback_c *callback, mAllocator_c *alloc, u32 bufferOption, int nView, u32 *pSize) {
|
||||
mMdlFile = mdlFile;
|
||||
mAnmFile = anmFile;
|
||||
|
||||
nw4r::g3d::ResMdl resMdl = mMdlFile.GetResMdl(mdlName);
|
||||
if (!mMdl.create(resMdl, callback, alloc, bufferOption, nView, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nw4r::g3d::ResAnmChr resAnm = mAnmFile.GetResAnmChr(anmName);
|
||||
if (!resAnm.mAnmChr.IsValid()) {
|
||||
resAnm = mMdlFile.GetResAnmChr(anmName);
|
||||
}
|
||||
u32 oldSize;
|
||||
if (pSize != nullptr) {
|
||||
oldSize = *pSize;
|
||||
}
|
||||
|
||||
if (!mAnm.create(resMdl, resAnm, alloc, pSize)) {
|
||||
mMdl.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pSize != nullptr) {
|
||||
*pSize += oldSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mdlAnmChr::create(void *resFile, const char *mdlName, const char *anmName, mAllocator_c *alloc, u32 bufferOption,
|
||||
int nView, u32 *pSize) {
|
||||
return create(resFile, resFile, mdlName, anmName, nullptr, alloc, bufferOption, nView, pSize);
|
||||
}
|
||||
|
||||
void mdlAnmChr::setAnm(const char *name, playMode_e mode, f32 blend) {
|
||||
nw4r::g3d::ResAnmChr anm = mAnmFile.GetResAnmChr(name);
|
||||
if (!anm.mAnmChr.IsValid()) {
|
||||
anm = mMdlFile.GetResAnmChr(name);
|
||||
}
|
||||
mAnm.setAnm(mMdl, anm, mode);
|
||||
mMdl.setAnm(mAnm, blend);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,60 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_anmshp.h>
|
||||
#include <nw4r/g3d/g3d_anmshp.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
anmShp_c::~anmShp_c() {}
|
||||
|
||||
int anmShp_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_SHP;
|
||||
}
|
||||
|
||||
bool anmShp_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmShp anm, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 tmp;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &tmp;
|
||||
}
|
||||
|
||||
// This might be an nw4r inline? Note that some of the roundings
|
||||
// are no-ops that still emit instructions because mwcc doesn't do
|
||||
// math
|
||||
u32 numEntries = mdl.GetResVtxPosNumEntries();
|
||||
*pSize = ROUND_UP(ROUND_UP(numEntries * 2 + 0x38, 0x04) + numEntries * 0x0C, 0x04);
|
||||
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjShpRes::Construct(&mAllocator, &tmp, anm, mdl, 0);
|
||||
if (!mpAnmObj->Bind(mdl)) {
|
||||
remove();
|
||||
return false;
|
||||
} else {
|
||||
setFrmCtrlDefault(anm, PLAY_MODE_4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void anmShp_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmShp anm, m3d::playMode_e mode) {
|
||||
mdl.removeAnm((nw4r::g3d::ScnMdlSimple::AnmObjType)getType());
|
||||
mpAnmObj->Release();
|
||||
mpFrameHeap->free(0x3);
|
||||
u32 tmp;
|
||||
mpAnmObj = nw4r::g3d::AnmObjShpRes::Construct(&mAllocator, &tmp, anm, mdl.getResMdl(), 0);
|
||||
mpAnmObj->Bind(mdl.getResMdl());
|
||||
setFrmCtrlDefault(anm, mode);
|
||||
}
|
||||
|
||||
void anmShp_c::setFrmCtrlDefault(nw4r::g3d::ResAnmShp &anm, m3d::playMode_e mode) {
|
||||
if (mode == PLAY_MODE_4) {
|
||||
mode = anm.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
|
||||
}
|
||||
set(anm.GetNumFrame(), mode, 1.0f, -1.0f);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,191 @@
|
||||
#include <egg/core/eggFrmHeap.h>
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_anmtexpat.h>
|
||||
#include <m/m_heap.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
int anmTexPat_c::child_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXPAT;
|
||||
}
|
||||
|
||||
anmTexPat_c::child_c::~child_c() {}
|
||||
|
||||
u32 anmTexPat_c::child_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, bool b) {
|
||||
u32 size = 0;
|
||||
nw4r::g3d::AnmObjTexPatRes::Construct(nullptr, &size, pat, mdl, false);
|
||||
if (b) {
|
||||
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool anmTexPat_c::child_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
*pSize = child_c::heapCost(mdl, pat, false);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjTexPatRes::Construct(&mAllocator, nullptr, pat, mdl, false);
|
||||
|
||||
if (!mpAnmObj->Bind(mdl)) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
setFrmCtrlDefault(pat, PLAY_MODE_4);
|
||||
return true;
|
||||
}
|
||||
|
||||
void anmTexPat_c::child_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmTexPat pat, m3d::playMode_e mode) {
|
||||
releaseAnm();
|
||||
mpAnmObj = nw4r::g3d::AnmObjTexPatRes::Construct(&mAllocator, nullptr, pat, mdl.getResMdl(), false);
|
||||
mpAnmObj->Bind(mdl.getResMdl());
|
||||
setFrmCtrlDefault(pat, mode);
|
||||
}
|
||||
|
||||
void anmTexPat_c::child_c::releaseAnm() {
|
||||
if (mpAnmObj != nullptr) {
|
||||
mpAnmObj->Release();
|
||||
mpFrameHeap->free(3);
|
||||
mpAnmObj = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void anmTexPat_c::child_c::setFrmCtrlDefault(nw4r::g3d::ResAnmTexPat &pat, playMode_e mode) {
|
||||
if (mode == PLAY_MODE_4) {
|
||||
mode = pat.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
|
||||
}
|
||||
set(pat.GetNumFrame(), mode, 1.0f, -1.0f);
|
||||
}
|
||||
|
||||
u32 anmTexPat_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, s32 num, bool b) {
|
||||
u32 size = 0;
|
||||
nw4r::g3d::AnmObjTexPatOverride::Construct(nullptr, &size, mdl, num);
|
||||
size += ROUND_UP(num * sizeof(child_c), 0x20);
|
||||
u32 childCost = child_c::heapCost(mdl, pat, true);
|
||||
size += num * ROUND_UP(childCost, 0x20);
|
||||
|
||||
if (b) {
|
||||
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool anmTexPat_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, mAllocator_c *alloc, u32 *pSize, s32 num) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size = 0;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
*pSize = heapCost(mdl, pat, num, false);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjTexPatOverride::Construct(&mAllocator, nullptr, mdl, num);
|
||||
|
||||
// TODO inline?
|
||||
mpChildren = (child_c *)MEMAllocFromAllocator(&mAllocator, ROUND_UP(num * sizeof(child_c), 0x20));
|
||||
|
||||
nw4r::g3d::AnmObjTexPatOverride *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
|
||||
child_c *child = mpChildren;
|
||||
for (int i = 0; i < num; i++) {
|
||||
new (child) child_c();
|
||||
if (!child->create(mdl, pat, &mAllocator, nullptr)) {
|
||||
mHeap::destroyFrmHeap(mpFrameHeap);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
obj->Attach(i, nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatRes>(child->getAnimObj()));
|
||||
} else {
|
||||
child->releaseAnm();
|
||||
}
|
||||
child++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
anmTexPat_c::~anmTexPat_c() {
|
||||
anmTexPat_c::remove();
|
||||
}
|
||||
|
||||
int anmTexPat_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXPAT;
|
||||
}
|
||||
|
||||
void anmTexPat_c::remove() {
|
||||
nw4r::g3d::AnmObjTexPatOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
|
||||
if (o != nullptr && mpChildren != 0) {
|
||||
int size = o->Size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
mpChildren[i].remove();
|
||||
}
|
||||
mpChildren = nullptr;
|
||||
}
|
||||
banm_c::remove();
|
||||
}
|
||||
|
||||
void anmTexPat_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmTexPat pat, s32 idx, playMode_e mode) {
|
||||
nw4r::g3d::AnmObjTexPatOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
|
||||
o->Detach(idx);
|
||||
mpChildren[idx].setAnm(mdl, pat, mode);
|
||||
|
||||
nw4r::g3d::AnmObjTexPatRes *res =
|
||||
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatRes>(mpChildren[idx].getAnimObj());
|
||||
o->Attach(idx, res);
|
||||
}
|
||||
|
||||
void anmTexPat_c::play() {
|
||||
nw4r::g3d::AnmObjTexPatOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
|
||||
int size = o->Size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
play(i);
|
||||
}
|
||||
}
|
||||
|
||||
void anmTexPat_c::play(s32 idx) {
|
||||
if (mpChildren[idx].IsBound()) {
|
||||
mpChildren[idx].play();
|
||||
}
|
||||
}
|
||||
|
||||
f32 anmTexPat_c::getFrame(s32 idx) const {
|
||||
return mpChildren[idx].getFrame();
|
||||
}
|
||||
|
||||
void anmTexPat_c::setFrame(f32 f, s32 idx) {
|
||||
mpChildren[idx].setFrameOnly(f);
|
||||
}
|
||||
|
||||
void anmTexPat_c::setRate(f32 f, s32 idx) {
|
||||
mpChildren[idx].setRate(f);
|
||||
}
|
||||
|
||||
bool anmTexPat_c::isStop(s32 idx) const {
|
||||
return mpChildren[idx].isStop();
|
||||
}
|
||||
|
||||
f32 anmTexPat_c::getFrameMax(s32 idx) const {
|
||||
return mpChildren[idx].getEndFrame();
|
||||
}
|
||||
|
||||
void anmTexPat_c::setFrameStart(f32 f, s32 idx) {
|
||||
mpChildren[idx].setStartFrame(f);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,214 @@
|
||||
#include <egg/core/eggFrmHeap.h>
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_anmtexsrt.h>
|
||||
#include <m/m_heap.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
int anmTexSrt_c::child_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXSRT;
|
||||
}
|
||||
|
||||
anmTexSrt_c::child_c::~child_c() {}
|
||||
|
||||
u32 anmTexSrt_c::child_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, bool b) {
|
||||
u32 size = 0;
|
||||
nw4r::g3d::AnmObjTexSrtRes::Construct(nullptr, &size, srt, mdl, false);
|
||||
if (b) {
|
||||
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool anmTexSrt_c::child_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
*pSize = child_c::heapCost(mdl, srt, false);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjTexSrtRes::Construct(&mAllocator, nullptr, srt, mdl, false);
|
||||
if (!mpAnmObj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mpAnmObj->Bind(mdl)) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
setFrmCtrlDefault(srt, PLAY_MODE_4);
|
||||
return true;
|
||||
}
|
||||
|
||||
void anmTexSrt_c::child_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmTexSrt srt, m3d::playMode_e mode) {
|
||||
releaseAnm();
|
||||
mpAnmObj = nw4r::g3d::AnmObjTexSrtRes::Construct(&mAllocator, nullptr, srt, mdl.getResMdl(), false);
|
||||
mpAnmObj->Bind(mdl.getResMdl());
|
||||
setFrmCtrlDefault(srt, mode);
|
||||
}
|
||||
|
||||
void anmTexSrt_c::child_c::releaseAnm() {
|
||||
if (mpAnmObj != nullptr) {
|
||||
mpAnmObj->Release();
|
||||
mpFrameHeap->free(3);
|
||||
mpAnmObj = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void anmTexSrt_c::child_c::setFrmCtrlDefault(nw4r::g3d::ResAnmTexSrt &srt, playMode_e mode) {
|
||||
if (mode == PLAY_MODE_4) {
|
||||
mode = srt.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
|
||||
}
|
||||
set(srt.GetNumFrame(), mode, 1.0f, -1.0f);
|
||||
}
|
||||
|
||||
u32 anmTexSrt_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, s32 num, bool b) {
|
||||
u32 size = 0;
|
||||
nw4r::g3d::AnmObjTexSrtOverride::Construct(nullptr, &size, mdl, num);
|
||||
size += ROUND_UP(num * sizeof(child_c), 0x20);
|
||||
u32 childCost = child_c::heapCost(mdl, srt, true);
|
||||
size += num * ROUND_UP(childCost, 0x20);
|
||||
|
||||
if (b) {
|
||||
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool anmTexSrt_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, mAllocator_c *alloc, u32 *pSize, s32 num) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size = 0;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
*pSize = heapCost(mdl, srt, num, false);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjTexSrtOverride::Construct(&mAllocator, nullptr, mdl, num);
|
||||
if (!mpAnmObj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO inline?
|
||||
mpChildren = (child_c *)MEMAllocFromAllocator(&mAllocator, ROUND_UP(num * sizeof(child_c), 0x20));
|
||||
if (!mpChildren) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
nw4r::g3d::AnmObjTexSrtOverride *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
|
||||
child_c *child = mpChildren;
|
||||
for (int i = 0; i < num; i++) {
|
||||
new (child) child_c();
|
||||
if (!child->create(mdl, srt, &mAllocator, nullptr)) {
|
||||
mHeap::destroyFrmHeap(mpFrameHeap);
|
||||
EGG::Heap::free(mpFrameHeap, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
obj->Attach(i, nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtRes>(child->getAnimObj()));
|
||||
} else {
|
||||
child->releaseAnm();
|
||||
}
|
||||
child++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
anmTexSrt_c::~anmTexSrt_c() {
|
||||
anmTexSrt_c::remove();
|
||||
}
|
||||
|
||||
int anmTexSrt_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXSRT;
|
||||
}
|
||||
|
||||
void anmTexSrt_c::remove() {
|
||||
nw4r::g3d::AnmObjTexSrtOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
|
||||
if (o != nullptr && mpChildren != 0) {
|
||||
int size = o->Size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
mpChildren[i].remove();
|
||||
}
|
||||
mpChildren = nullptr;
|
||||
}
|
||||
banm_c::remove();
|
||||
}
|
||||
|
||||
void anmTexSrt_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmTexSrt srt, s32 idx, playMode_e mode) {
|
||||
nw4r::g3d::AnmObjTexSrtOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
|
||||
o->Detach(idx);
|
||||
mpChildren[idx].setAnm(mdl, srt, mode);
|
||||
|
||||
nw4r::g3d::AnmObjTexSrtRes *res =
|
||||
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtRes>(mpChildren[idx].getAnimObj());
|
||||
o->Attach(idx, res);
|
||||
}
|
||||
|
||||
void anmTexSrt_c::play() {
|
||||
nw4r::g3d::AnmObjTexSrtOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
|
||||
int size = o->Size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
play(i);
|
||||
}
|
||||
}
|
||||
|
||||
void anmTexSrt_c::play(s32 idx) {
|
||||
if (mpChildren[idx].IsBound()) {
|
||||
mpChildren[idx].play();
|
||||
}
|
||||
}
|
||||
|
||||
f32 anmTexSrt_c::getFrame(s32 idx) const {
|
||||
return mpChildren[idx].getFrame();
|
||||
}
|
||||
|
||||
void anmTexSrt_c::setFrame(f32 f, s32 idx) {
|
||||
mpChildren[idx].setFrameOnly(f);
|
||||
}
|
||||
|
||||
void anmTexSrt_c::setRate(f32 f, s32 idx) {
|
||||
mpChildren[idx].setRate(f);
|
||||
}
|
||||
|
||||
bool anmTexSrt_c::isStop(s32 idx) const {
|
||||
return mpChildren[idx].isStop();
|
||||
}
|
||||
|
||||
bool anmTexSrt_c::checkFrame(f32 f, s32 idx) const {
|
||||
return mpChildren[idx].checkFrame(f);
|
||||
}
|
||||
|
||||
void anmTexSrt_c::setPlayMode(playMode_e mode, s32 idx) {
|
||||
mpChildren[idx].setPlayState(mode);
|
||||
}
|
||||
|
||||
f32 anmTexSrt_c::getFrameMax(s32 idx) const {
|
||||
return mpChildren[idx].getEndFrame();
|
||||
}
|
||||
|
||||
void anmTexSrt_c::setFrameStart(f32 f, s32 idx) {
|
||||
mpChildren[idx].setStartFrame(f);
|
||||
}
|
||||
|
||||
f32 anmTexSrt_c::getFrameStart(s32 idx) const {
|
||||
return mpChildren[idx].getStartFrame();
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_anmvis.h>
|
||||
#include <nw4r/g3d/g3d_anmvis.h>
|
||||
#include <nw4r/g3d/g3d_resanmvis.h>
|
||||
#include <nw4r/g3d/g3d_resmdl.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
anmVis_c::~anmVis_c() {}
|
||||
|
||||
int anmVis_c::getType() const {
|
||||
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_VIS;
|
||||
}
|
||||
|
||||
bool anmVis_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmVis anm, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 tmp;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &tmp;
|
||||
}
|
||||
|
||||
nw4r::g3d::AnmObjVisRes::Construct(nullptr, pSize, anm, mdl);
|
||||
if (!createAllocator(alloc, pSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpAnmObj = nw4r::g3d::AnmObjVisRes::Construct(&mAllocator, &tmp, anm, mdl);
|
||||
if (!mpAnmObj->Bind(mdl)) {
|
||||
remove();
|
||||
return false;
|
||||
} else {
|
||||
setFrmCtrlDefault(anm, PLAY_MODE_4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void anmVis_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmVis anm, m3d::playMode_e mode) {
|
||||
mdl.removeAnm((nw4r::g3d::ScnMdlSimple::AnmObjType)getType());
|
||||
mpAnmObj->Release();
|
||||
mpFrameHeap->free(0x3);
|
||||
u32 tmp;
|
||||
mpAnmObj = nw4r::g3d::AnmObjVisRes::Construct(&mAllocator, &tmp, anm, mdl.getResMdl());
|
||||
mpAnmObj->Bind(mdl.getResMdl());
|
||||
setFrmCtrlDefault(anm, mode);
|
||||
}
|
||||
|
||||
void anmVis_c::setFrmCtrlDefault(nw4r::g3d::ResAnmVis &anm, m3d::playMode_e mode) {
|
||||
if (mode == PLAY_MODE_4) {
|
||||
mode = anm.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
|
||||
}
|
||||
set(anm.GetNumFrame(), mode, 1.0f, -1.0f);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_banm.h>
|
||||
#include <m/m_heap.h>
|
||||
|
||||
namespace m3d {
|
||||
banm_c::~banm_c() {
|
||||
banm_c::remove();
|
||||
}
|
||||
|
||||
void banm_c::remove() {
|
||||
if (mpAnmObj != nullptr) {
|
||||
mpAnmObj->DetachFromParent();
|
||||
mpAnmObj->Destroy();
|
||||
mpAnmObj = nullptr;
|
||||
}
|
||||
|
||||
if (mpFrameHeap != nullptr) {
|
||||
mHeap::destroyFrmHeap(mpFrameHeap);
|
||||
mpFrameHeap = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool banm_c::createAllocator(mAllocator_c *alloc, u32 *pStart) {
|
||||
// TODO understand this maybe?
|
||||
int i1 = mHeap::frmHeapCost(*pStart, 0x20);
|
||||
int i2 = mHeap::frmHeapCost(0, 0x20);
|
||||
i2 = ROUND_UP(i1, 0x20) - i2;
|
||||
i1 = mHeap::frmHeapCost(i2, 0x20);
|
||||
*pStart = ROUND_UP(i1, 0x20);
|
||||
mpFrameHeap = mHeap::createFrmHeap(i2, (EGG::Heap *)alloc->mHeap, "アニメ切り替え用アロケータ(m3d::banm_c::m_heap)",
|
||||
internal::l_alignment, 0);
|
||||
mAllocator.attach(mpFrameHeap, 0x20);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool banm_c::IsBound() const {
|
||||
if (mpAnmObj == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return mpAnmObj->TestAnmFlag(nw4r::g3d::AnmObj::ANMFLAG_ISBOUND);
|
||||
}
|
||||
|
||||
void banm_c::play() {}
|
||||
|
||||
f32 banm_c::getFrame() const {
|
||||
return mpAnmObj->GetFrame();
|
||||
}
|
||||
|
||||
void banm_c::setFrameOnly(f32 frame) {
|
||||
mpAnmObj->SetFrame(frame);
|
||||
}
|
||||
|
||||
f32 banm_c::getRate() const {
|
||||
return mpAnmObj->GetUpdateRate();
|
||||
}
|
||||
|
||||
void banm_c::setRate(f32 f) {
|
||||
mpAnmObj->SetUpdateRate(f);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,252 @@
|
||||
#include <egg/core/eggColorFader.h>
|
||||
#include <egg/core/eggHeap.h>
|
||||
#include <egg/gfx/eggDrawGX.h>
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_bline.h>
|
||||
#include <nw4r/g3d/g3d_light.h>
|
||||
#include <nw4r/g3d/g3d_state.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
blineMat_c::~blineMat_c() {
|
||||
remove();
|
||||
}
|
||||
|
||||
bool blineMat_c::create(mAllocator_c *pAllocator, int numLines, u16 numLinePts, f32 width, f32 repeat,
|
||||
nw4r::ut::Color &color, EGG::ResTIMG *pTex, bool p9) {
|
||||
if (!proc_c::create(pAllocator, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
nw4r::ut::List_Init(&mLines, 0);
|
||||
if (numLines) {
|
||||
mpLineArr = new (pAllocator) bline_c[numLines];
|
||||
|
||||
if (!mpLineArr) {
|
||||
return false;
|
||||
}
|
||||
bline_c *pLineArr = mpLineArr;
|
||||
EGG::Heap *pHeap = pAllocator->mHeap;
|
||||
for (int i = 0; i < numLines; ++i) {
|
||||
if (!pLineArr->create(pHeap, numLinePts, width, repeat, color)) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
nw4r::ut::List_Append(&mLines, pLineArr);
|
||||
pLineArr++;
|
||||
}
|
||||
}
|
||||
|
||||
mLineArrNum = numLines;
|
||||
mpTex = pTex;
|
||||
field_0x4A = p9;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void blineMat_c::remove() {
|
||||
if (mpLineArr) {
|
||||
delete[] mpLineArr;
|
||||
mpLineArr = nullptr;
|
||||
}
|
||||
scnLeaf_c::remove();
|
||||
}
|
||||
|
||||
void blineMat_c::update() {
|
||||
nw4r::math::MTX34 camMtx;
|
||||
mVec3_c vec;
|
||||
|
||||
getCurrentCamera().GetCameraMtx(&camMtx);
|
||||
PSMTXInverse(camMtx, camMtx);
|
||||
PSMTXMultVec(camMtx, mVec3_c::zero, vec);
|
||||
|
||||
for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
|
||||
line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
|
||||
if ((line->mFlags & 1) == 0) {
|
||||
line->update(&vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bline_c *blineMat_c::getLine(u16 idx) {
|
||||
return (bline_c *)nw4r::ut::List_GetNth(&mLines, idx);
|
||||
}
|
||||
|
||||
void blineMat_c::setupGX(bool bTransparent) {
|
||||
EGG::DrawGX::LoadTexture(mpTex, GX_TEXMAP0);
|
||||
if (field_0x4A) {
|
||||
u32 mask_diff_color, mask_diff_alpha, mask_spec_color, mask_spec_alpha;
|
||||
nw4r::g3d::AmbLightObj ambObj;
|
||||
|
||||
nw4r::g3d::G3DState::LoadLightSet(0, &mask_diff_color, &mask_diff_alpha, &mask_spec_color, &mask_spec_alpha,
|
||||
&ambObj);
|
||||
|
||||
nw4r::ut::Color ambColor(0xFF, 0xFF, 0xFF, 0xFF);
|
||||
nw4r::ut::Color matColor(0xFF, 0xFF, 0xFF, 0xFF);
|
||||
GXSetChanMatColor(GX_COLOR0, matColor);
|
||||
|
||||
ambColor.r = ambObj.r;
|
||||
ambColor.g = ambObj.g;
|
||||
ambColor.b = ambObj.b;
|
||||
ambColor.a = ambObj.a;
|
||||
GXSetChanAmbColor(GX_COLOR0, ambColor);
|
||||
|
||||
GXSetNumChans(1);
|
||||
GXSetChanCtrl(GX_COLOR0, TRUE, GX_SRC_REG, GX_SRC_REG, (GXLightID)mask_diff_color, GX_DF_CLAMP, GX_AF_NONE);
|
||||
GXSetChanCtrl(GX_ALPHA0, FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
|
||||
GXSetNumTevStages(2);
|
||||
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
||||
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_RASC, GX_CC_CPREV, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
|
||||
} else {
|
||||
GXSetNumChans(0);
|
||||
GXSetNumTevStages(1);
|
||||
}
|
||||
GXSetNumTexGens(1);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, 0, GX_DUALMTX_IDENT);
|
||||
GXSetNumIndStages(0);
|
||||
GXSetTevDirect(GX_TEVSTAGE0);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
|
||||
GXSetZCompLoc(1);
|
||||
if (!bTransparent) {
|
||||
GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_SET);
|
||||
GXSetZMode(TRUE, GX_LEQUAL, TRUE);
|
||||
} else {
|
||||
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
|
||||
GXSetZMode(TRUE, GX_LEQUAL, FALSE);
|
||||
}
|
||||
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
|
||||
nw4r::ut::Color fogColor = 0x0;
|
||||
GXSetFog(GX_FOG_NONE, fogColor, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
GXSetFogRangeAdj(FALSE, 0, NULL);
|
||||
GXSetCullMode(GX_CULL_BACK);
|
||||
GXSetDither(1);
|
||||
GXSetClipMode(GX_CLIP_ENABLE);
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||
GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
|
||||
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_RGB8, 6);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_F32, 0);
|
||||
|
||||
nw4r::math::MTX34 camMtx;
|
||||
getCurrentCamera().GetCameraMtx(&camMtx);
|
||||
GXLoadPosMtxImm(camMtx, 0);
|
||||
GXLoadNrmMtxImm(camMtx, 0);
|
||||
GXSetCurrentMtx(0);
|
||||
}
|
||||
|
||||
void blineMat_c::drawOpa() {
|
||||
update();
|
||||
setupGX(false);
|
||||
for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
|
||||
line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
|
||||
if ((line->mFlags & 1) == 0 && line->mColor.a == 0xFF) {
|
||||
line->draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blineMat_c::drawXlu() {
|
||||
update();
|
||||
setupGX(true);
|
||||
for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
|
||||
line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
|
||||
if ((line->mFlags & 1) == 0 && line->mColor.a != 0xFF) {
|
||||
line->draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bline_c::~bline_c() {
|
||||
remove();
|
||||
}
|
||||
|
||||
bool bline_c::create(EGG::Heap *pHeap, u16 numPts, f32 width, f32 repeat, const nw4r::ut::Color &color) {
|
||||
mpPathArr = new (pHeap) mVec3_c[numPts];
|
||||
if (!mpPathArr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpVtxPosArr = new (pHeap) VtxPos[numPts];
|
||||
if (!mpVtxPosArr) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
mpVtxNrmArr = new (pHeap) VtxNrm[numPts];
|
||||
if (!mpVtxNrmArr) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
mpVtxTexArr = new (pHeap) VtxTex[numPts];
|
||||
if (!mpVtxTexArr) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
mPathNum = numPts;
|
||||
mVtxNum = numPts;
|
||||
mWidth = width;
|
||||
mColor = color;
|
||||
mTexRepeat = repeat;
|
||||
field_0x2C = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void bline_c::remove() {
|
||||
if (mpPathArr) {
|
||||
delete[] mpPathArr;
|
||||
mpPathArr = nullptr;
|
||||
}
|
||||
if (mpVtxPosArr) {
|
||||
delete[] mpVtxPosArr;
|
||||
mpVtxPosArr = nullptr;
|
||||
}
|
||||
if (mpVtxNrmArr) {
|
||||
delete[] mpVtxNrmArr;
|
||||
mpVtxNrmArr = nullptr;
|
||||
}
|
||||
if (mpVtxTexArr) {
|
||||
delete[] mpVtxTexArr;
|
||||
mpVtxTexArr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void bline_c::update(mVec3_c *startPos) {}
|
||||
|
||||
void bline_c::draw() {
|
||||
GXSetTevColor(GX_TEVREG0, mColor);
|
||||
|
||||
VtxPos *vtxPos = mpVtxPosArr;
|
||||
VtxNrm *vtxNrm = mpVtxNrmArr;
|
||||
VtxTex *vtxTex = mpVtxTexArr;
|
||||
|
||||
GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, mVtxNum * 2);
|
||||
|
||||
for (int i = 0; i < mVtxNum; i++) {
|
||||
// First Vtx
|
||||
GXPosition3f32(vtxPos->pos1.x, vtxPos->pos1.y, vtxPos->pos1.z);
|
||||
GXNormal3s8(vtxNrm->nrm1.x, vtxNrm->nrm1.y, vtxNrm->nrm1.z);
|
||||
GXTexCoord2f32(0.0f, vtxTex->tex);
|
||||
|
||||
// Second Vtx
|
||||
GXPosition3f32(vtxPos->pos2.x, vtxPos->pos2.y, vtxPos->pos2.z);
|
||||
GXNormal3s8(vtxNrm->nrm2.x, vtxNrm->nrm2.y, vtxNrm->nrm2.z);
|
||||
GXTexCoord2f32(0.0f, vtxTex->tex);
|
||||
|
||||
vtxPos++;
|
||||
vtxNrm++;
|
||||
vtxTex++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,228 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_bmdl.h>
|
||||
#include <nw4r/g3d/g3d_scnmdl.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
bmdl_c::~bmdl_c() {
|
||||
remove();
|
||||
}
|
||||
|
||||
int bmdl_c::getType() const {
|
||||
return SCN_LEAF_MODEL;
|
||||
}
|
||||
|
||||
int bmdl_c::getMatID(const char *name) const {
|
||||
return m3d::getMatID(getResMdl(), name);
|
||||
}
|
||||
|
||||
int bmdl_c::getNodeID(const char *name) const {
|
||||
return m3d::getNodeID(getResMdl(), name);
|
||||
}
|
||||
|
||||
bool bmdl_c::getNodeWorldMtx(u32 p1, nw4r::math::MTX34 *out) const {
|
||||
return nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf)->GetScnMtxPos(out,
|
||||
nw4r::g3d::ScnObj::MTX_TYPE_WORLD, p1);
|
||||
}
|
||||
|
||||
bool bmdl_c::getNodeWorldMtxMultVecZero(u32 p1, nw4r::math::VEC3 &out) const {
|
||||
nw4r::math::MTX34 mtx;
|
||||
if (!getNodeWorldMtx(p1, &mtx)) {
|
||||
return false;
|
||||
} else {
|
||||
out.x = mtx[0][3];
|
||||
out.y = mtx[1][3];
|
||||
out.z = mtx[2][3];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool bmdl_c::getNodeWorldMtxMultVec(u32 p1, nw4r::math::VEC3 &in, nw4r::math::VEC3 &out) const {
|
||||
nw4r::math::MTX34 mtx;
|
||||
if (!getNodeWorldMtx(p1, &mtx)) {
|
||||
return false;
|
||||
} else {
|
||||
PSMTXMultVec(mtx, in, out);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setAnm(banm_c &anm) {
|
||||
nw4r::g3d::ScnMdlSimple *mdl;
|
||||
if (anm.getType() == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_SHP) {
|
||||
mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
mdl->SetAnmObj(anm.getAnimObj(), nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_NOT_SPECIFIED);
|
||||
} else {
|
||||
mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
|
||||
if (anm.getType() == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR) {
|
||||
mpCurrentAnm = &anm;
|
||||
}
|
||||
mdl->SetAnmObj(anm.getAnimObj(), nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_NOT_SPECIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::play() {
|
||||
if (mpCurrentAnm != nullptr) {
|
||||
mpCurrentAnm->play();
|
||||
}
|
||||
}
|
||||
|
||||
nw4r::g3d::ResMdl bmdl_c::getResMdl() const {
|
||||
return nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf)->GetResMdl();
|
||||
}
|
||||
|
||||
nw4r::g3d::ResMat bmdl_c::getResMat(u32 index) const {
|
||||
nw4r::g3d::ResMdl mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf)->GetResMdl();
|
||||
return mdl.GetResMat(index);
|
||||
}
|
||||
|
||||
void bmdl_c::removeAnm(nw4r::g3d::ScnMdlSimple::AnmObjType type) {
|
||||
nw4r::g3d::ScnMdlSimple *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
|
||||
if (type == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR) {
|
||||
mpCurrentAnm = nullptr;
|
||||
}
|
||||
mdl->RemoveAnmObj(type);
|
||||
}
|
||||
|
||||
nw4r::g3d::AnmObj *bmdl_c::getAnmObj(nw4r::g3d::ScnMdlSimple::AnmObjType type) const {
|
||||
nw4r::g3d::ScnMdlSimple *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
|
||||
return mdl->GetAnmObj(type);
|
||||
}
|
||||
|
||||
void bmdl_c::setTevColor(u32 idx, GXTevRegID tevId, GXColor color, bool bMarkDirty) {
|
||||
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
|
||||
if (mdl) {
|
||||
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, idx);
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
|
||||
resMatTevClr.GXSetTevColor(tevId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
} else {
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = getResMat(idx).GetResMatTevColor();
|
||||
resMatTevClr.GXSetTevColor(tevId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setTevColorAll(GXTevRegID tevId, GXColor color, bool bMarkDirty) {
|
||||
nw4r::g3d::ResMdl resMdl = getResMdl();
|
||||
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
if (mdl) {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
|
||||
resMatTevClr.GXSetTevColor(tevId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
}
|
||||
} else {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = resMdl.GetResMat(i).GetResMatTevColor();
|
||||
resMatTevClr.GXSetTevColor(tevId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setTevKColor(u32 idx, GXTevKColorID tevKId, GXColor color, bool bMarkDirty) {
|
||||
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
|
||||
if (mdl) {
|
||||
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, idx);
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
|
||||
resMatTevClr.GXSetTevKColor(tevKId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
} else {
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = getResMat(idx).GetResMatTevColor();
|
||||
resMatTevClr.GXSetTevKColor(tevKId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setTevKColorAll(GXTevKColorID tevKId, GXColor color, bool bMarkDirty) {
|
||||
nw4r::g3d::ResMdl resMdl = getResMdl();
|
||||
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
if (mdl) {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
|
||||
resMatTevClr.GXSetTevKColor(tevKId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
}
|
||||
} else {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ResMatTevColor resMatTevClr = resMdl.GetResMat(i).GetResMatTevColor();
|
||||
resMatTevClr.GXSetTevKColor(tevKId, color);
|
||||
resMatTevClr.DCStore(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setBlendModeAll(GXBlendMode blendMode, GXBlendFactor srcFactor, GXBlendFactor dstFactor, GXLogicOp op,
|
||||
bool bMarkDirty) {
|
||||
nw4r::g3d::ResMdl resMdl = getResMdl();
|
||||
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
if (mdl) {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
|
||||
nw4r::g3d::ResMatPix resMatPix = matAccess.GetResMatPix(bMarkDirty);
|
||||
resMatPix.GXSetBlendMode(blendMode, srcFactor, dstFactor, op);
|
||||
resMatPix.DCStore(false);
|
||||
}
|
||||
} else {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ResMatPix resMatPix = resMdl.GetResMat(i).GetResMatPix();
|
||||
resMatPix.GXSetBlendMode(blendMode, srcFactor, dstFactor, op);
|
||||
resMatPix.DCStore(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setCullMode(u32 matId, GXCullMode cullMode, bool bMarkDirty) {
|
||||
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
if (mdl) {
|
||||
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, matId);
|
||||
nw4r::g3d::ResGenMode resGenMode = matAccess.GetResGenMode(bMarkDirty);
|
||||
resGenMode.GXSetCullMode(cullMode);
|
||||
} else {
|
||||
nw4r::g3d::ResGenMode resGenMode = getResMat(matId).GetResGenMode();
|
||||
resGenMode.GXSetCullMode(cullMode);
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setCullModeAll(GXCullMode cullMode, bool bMarkDirty) {
|
||||
// TODO Extra stack allocation?
|
||||
nw4r::g3d::ResMdl resMdl = getResMdl();
|
||||
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
|
||||
if (mdl) {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
|
||||
nw4r::g3d::ResGenMode resGenMode = matAccess.GetResGenMode(bMarkDirty);
|
||||
resGenMode.GXSetCullMode(cullMode);
|
||||
}
|
||||
} else {
|
||||
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
|
||||
nw4r::g3d::ResMat resMat = getResMat(i);
|
||||
nw4r::g3d::ResGenMode resGenMode = resMat.GetResGenMode();
|
||||
resGenMode.GXSetCullMode(cullMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bmdl_c::setMatVisible(u32 matId, bool bVisble) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int bmdl_c::setMatTexture(char *name, GXTexObj *texObj, bool copy, void *unk, int, int) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool bmdl_c::getBounds(mVec3_c *min, mVec3_c *max) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void bmdl_c::remove() {
|
||||
mpCurrentAnm = nullptr;
|
||||
scnLeaf_c::remove();
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,73 @@
|
||||
#include <m/m3d/m_calc_ratio.h>
|
||||
#include <nw4r/math/math_arithmetic.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
calcRatio_c::calcRatio_c() {
|
||||
mf1 = 0.0f;
|
||||
mf2 = 1.0f;
|
||||
mf3 = 0.0f;
|
||||
mf4 = 0.0f;
|
||||
mf5 = 1.0f;
|
||||
mb1 = 0;
|
||||
mb2 = 0;
|
||||
}
|
||||
|
||||
calcRatio_c::~calcRatio_c() {}
|
||||
|
||||
void calcRatio_c::remove() {
|
||||
mb1 = 0;
|
||||
reset();
|
||||
}
|
||||
|
||||
void calcRatio_c::reset() {
|
||||
mf1 = 0.0f;
|
||||
mf2 = 1.0f;
|
||||
mf4 = 0.0f;
|
||||
mf5 = 1.0f;
|
||||
}
|
||||
|
||||
void calcRatio_c::offUpdate() {
|
||||
mb1 = 1;
|
||||
mb2 = 0;
|
||||
}
|
||||
|
||||
void calcRatio_c::set(f32 value) {
|
||||
if (value == 0.0f) {
|
||||
reset();
|
||||
return;
|
||||
}
|
||||
mf1 = 1.0f;
|
||||
mf2 = 0.0f;
|
||||
mf4 = 1.0f;
|
||||
mf5 = 0.0f;
|
||||
mb2 = 1;
|
||||
mf3 = 1.0f / value;
|
||||
}
|
||||
|
||||
void calcRatio_c::calc() {
|
||||
if (mf1 == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
mf2 += mf3;
|
||||
if (mf2 >= 1.0f) {
|
||||
reset();
|
||||
} else {
|
||||
mb2 = 1;
|
||||
f32 start = mf1;
|
||||
f32 tmp = start - start * mf2 * mf2;
|
||||
mf1 = tmp;
|
||||
f32 max = 1.0f - mf1;
|
||||
tmp = mf1 / start;
|
||||
f32 inv = nw4r::math::FInv(tmp + max);
|
||||
mf4 = tmp * inv;
|
||||
mf5 = max * inv;
|
||||
}
|
||||
}
|
||||
|
||||
bool calcRatio_c::isEnd() const {
|
||||
return mf1 == 0.0f;
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,133 @@
|
||||
#include <m/m3d/m_fanm.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
fanm_c::fanm_c() {
|
||||
mEndFrame = 0.0f;
|
||||
mCurrentFrame = 0.0f;
|
||||
mPlayState = 0.0f;
|
||||
}
|
||||
fanm_c::~fanm_c() {}
|
||||
|
||||
void fanm_c::play() {
|
||||
f32 frame = mpAnmObj->GetFrame();
|
||||
f32 rate = mpAnmObj->GetUpdateRate();
|
||||
bool rateWasNegative = rate < 0.0f;
|
||||
if (rateWasNegative) {
|
||||
rate *= -1.0f;
|
||||
}
|
||||
mCurrentFrame = frame;
|
||||
|
||||
f32 newFrame;
|
||||
if (rateWasNegative || (mPlayState & 2)) {
|
||||
if (frame >= rate + mStartFrame) {
|
||||
newFrame = frame - rate;
|
||||
} else if ((mPlayState & 1) == 0) {
|
||||
newFrame = frame + ((mEndFrame - rate) - mStartFrame);
|
||||
} else {
|
||||
newFrame = mStartFrame;
|
||||
}
|
||||
} else {
|
||||
newFrame = frame + rate;
|
||||
if ((mPlayState & 1) == 0) {
|
||||
if (newFrame >= mEndFrame) {
|
||||
newFrame = newFrame - mEndFrame;
|
||||
}
|
||||
} else {
|
||||
f32 t = mEndFrame - 1.0f;
|
||||
if (newFrame >= t) {
|
||||
newFrame = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mpAnmObj->SetFrame(newFrame);
|
||||
}
|
||||
|
||||
void fanm_c::set(f32 startFrame, playMode_e mode, f32 updateRate, f32 currentFrame) {
|
||||
if (currentFrame < 0.0f) {
|
||||
currentFrame = startFrame;
|
||||
if (mode == PLAY_MODE_1) {
|
||||
currentFrame = 0.0f;
|
||||
} else {
|
||||
currentFrame -= 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
mEndFrame = startFrame;
|
||||
mStartFrame = 0.0f;
|
||||
mpAnmObj->SetFrame(currentFrame);
|
||||
mpAnmObj->SetUpdateRate(updateRate);
|
||||
mPlayState = (u8)mode;
|
||||
mCurrentFrame = currentFrame;
|
||||
}
|
||||
|
||||
void fanm_c::set2(f32 startFrame, playMode_e mode, f32 endFrame, f32 rate, f32 currentFrame) {
|
||||
if (currentFrame < 0.0f) {
|
||||
currentFrame = rate < 0.0f ? endFrame - 1.0f : startFrame;
|
||||
}
|
||||
|
||||
mStartFrame = startFrame;
|
||||
mEndFrame = endFrame;
|
||||
mpAnmObj->SetFrame(currentFrame);
|
||||
mpAnmObj->SetUpdateRate(rate);
|
||||
mPlayState = (u8)mode;
|
||||
mCurrentFrame = currentFrame;
|
||||
}
|
||||
|
||||
// assumed name
|
||||
void fanm_c::setFrameOnly(f32 frame) {
|
||||
banm_c::setFrameOnly(frame);
|
||||
mCurrentFrame = frame;
|
||||
}
|
||||
|
||||
bool fanm_c::isStop() const {
|
||||
f32 frame = mpAnmObj->GetFrame();
|
||||
f32 rate = mpAnmObj->GetUpdateRate();
|
||||
if (rate < 0.0f || mPlayState == PLAY_MODE_3) {
|
||||
return frame <= mStartFrame;
|
||||
} else if (mPlayState == PLAY_MODE_1) {
|
||||
return frame >= mEndFrame - 1.0f;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fanm_c::checkFrame(f32 frame) const {
|
||||
f32 stored = mpAnmObj->GetFrame();
|
||||
if (mCurrentFrame == stored) {
|
||||
return stored == frame;
|
||||
}
|
||||
|
||||
f32 rate = mpAnmObj->GetUpdateRate();
|
||||
if (rate < 0.0f || (mPlayState & 2)) {
|
||||
if (mCurrentFrame > stored) {
|
||||
if (mCurrentFrame > frame && stored <= frame) {
|
||||
return true;
|
||||
}
|
||||
} else if (frame < mCurrentFrame || frame >= stored) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (mCurrentFrame < stored) {
|
||||
if (mCurrentFrame < frame && stored >= frame) {
|
||||
return true;
|
||||
}
|
||||
} else if (frame > mCurrentFrame || frame <= stored) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fanm_c::unk_802EAE70() const {
|
||||
f32 frame = mpAnmObj->GetFrame();
|
||||
f32 rate = mpAnmObj->GetUpdateRate();
|
||||
if (rate < 0.0f || (mPlayState & 2)) {
|
||||
return mCurrentFrame < frame;
|
||||
} else {
|
||||
return mCurrentFrame > frame;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,239 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_mdl.h>
|
||||
#include <nw4r/g3d/g3d_scnmdlsmpl.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
mdl_c::mdlCallback_c::mdlCallback_c() {
|
||||
mNumNode = 0;
|
||||
mpNodes = nullptr;
|
||||
mpBaseCallback = 0;
|
||||
mpAlloc = nullptr;
|
||||
}
|
||||
mdl_c::mdlCallback_c::~mdlCallback_c() {}
|
||||
|
||||
void mdl_c::mdlCallback_c::ExecCallbackA(nw4r::g3d::ChrAnmResult *result, nw4r::g3d::ResMdl mdl,
|
||||
nw4r::g3d::FuncObjCalcWorld *o) {
|
||||
u16 nodeId = o->GetNodeId();
|
||||
nw4r::g3d::ChrAnmResult *resPtr = &mpNodes[nodeId];
|
||||
if (mCalcRatio.is0x18() && !mCalcRatio.isEnd()) {
|
||||
if (!mCalcRatio.is0x19()) {
|
||||
*result = *resPtr;
|
||||
} else {
|
||||
u32 flags = result->mFlags;
|
||||
f32 f2 = mCalcRatio.get0x10();
|
||||
f32 f1 = mCalcRatio.get0x14();
|
||||
|
||||
// TODO clean up this code, what does it even do, why do operators
|
||||
// break
|
||||
if ((flags & 8) == 0) {
|
||||
result->VEC3_0x4.x = (result->VEC3_0x4.x * f1 + resPtr->VEC3_0x4.x * f2);
|
||||
result->VEC3_0x4.y = (result->VEC3_0x4.y * f1 + resPtr->VEC3_0x4.y * f2);
|
||||
result->VEC3_0x4.z = (result->VEC3_0x4.z * f1 + resPtr->VEC3_0x4.z * f2);
|
||||
} else {
|
||||
result->VEC3_0x4.x = (f1 + resPtr->VEC3_0x4.x * f2);
|
||||
result->VEC3_0x4.y = (f1 + resPtr->VEC3_0x4.y * f2);
|
||||
result->VEC3_0x4.z = (f1 + resPtr->VEC3_0x4.z * f2);
|
||||
}
|
||||
|
||||
nw4r::math::QUAT q1;
|
||||
nw4r::math::QUAT q2;
|
||||
|
||||
C_QUATMtx(q1, resPtr->mMtx);
|
||||
if ((flags & 0x20) == 0) {
|
||||
C_QUATMtx(q2, result->mMtx);
|
||||
} else {
|
||||
q2.x = 0.0f;
|
||||
q2.y = 0.0f;
|
||||
q2.z = 0.0f;
|
||||
q2.w = 1.0f;
|
||||
}
|
||||
|
||||
C_QUATSlerp(q1, q2, q1, f1);
|
||||
nw4r::math::VEC3 tmp;
|
||||
tmp.x = result->mMtx._03;
|
||||
tmp.y = result->mMtx._13;
|
||||
tmp.z = result->mMtx._23;
|
||||
PSMTXQuat(result->mMtx, q1);
|
||||
result->mMtx._03 = tmp.x;
|
||||
result->mMtx._13 = tmp.y;
|
||||
result->mMtx._23 = tmp.z;
|
||||
if ((flags & 0x40) == 0) {
|
||||
result->mMtx._03 = tmp.x * f1;
|
||||
result->mMtx._13 = tmp.y * f1;
|
||||
result->mMtx._23 = tmp.z * f1;
|
||||
}
|
||||
result->mMtx._03 += resPtr->mMtx._03 * f2;
|
||||
result->mMtx._13 += resPtr->mMtx._13 * f2;
|
||||
result->mMtx._23 += resPtr->mMtx._23 * f2;
|
||||
result->mFlags = result->mFlags & ~(0x80000000 | 0x00000040 | 0x00000020 | 0x00000008);
|
||||
*resPtr = *result;
|
||||
}
|
||||
} else {
|
||||
*resPtr = *result;
|
||||
}
|
||||
|
||||
if (mpBaseCallback != nullptr) {
|
||||
mpBaseCallback->timingA(nodeId, result, mdl);
|
||||
}
|
||||
}
|
||||
|
||||
void mdl_c::mdlCallback_c::ExecCallbackB(nw4r::g3d::WorldMtxManip *m, nw4r::g3d::ResMdl mdl,
|
||||
nw4r::g3d::FuncObjCalcWorld *o) {
|
||||
u16 nodeId = o->GetNodeId();
|
||||
if (mpBaseCallback != nullptr) {
|
||||
mpBaseCallback->timingB(nodeId, m, mdl);
|
||||
}
|
||||
// Not sure what this does
|
||||
u32 num = mdl.GetResNodeNumEntries();
|
||||
u32 nodeInc = nodeId + 1;
|
||||
u32 tmp = (nodeInc / num);
|
||||
o->SetNodeId(nodeInc - tmp * num);
|
||||
}
|
||||
|
||||
void mdl_c::mdlCallback_c::ExecCallbackC(nw4r::math::MTX34 *mat, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *) {
|
||||
if (mpBaseCallback != nullptr) {
|
||||
mpBaseCallback->timingC(mat, mdl);
|
||||
}
|
||||
mCalcRatio.offUpdate();
|
||||
}
|
||||
|
||||
bool mdl_c::mdlCallback_c::create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size = 0;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
mNumNode = mdl.GetResNodeNumEntries();
|
||||
size_t bufSize = mNumNode * sizeof(nw4r::g3d::ChrAnmResult);
|
||||
mpNodes = (nw4r::g3d::ChrAnmResult *)MEMAllocFromAllocator(alloc, bufSize);
|
||||
if (mpNodes == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*pSize = ROUND_UP(bufSize + ROUND_UP(*pSize, 0x04), 0x04);
|
||||
nw4r::g3d::ChrAnmResult *node = mpNodes;
|
||||
for (int i = 0; i < mNumNode; i++) {
|
||||
node->VEC3_0x4.x = 1.0f;
|
||||
node->VEC3_0x4.y = 1.0f;
|
||||
node->VEC3_0x4.z = 1.0f;
|
||||
PSMTXIdentity(node->mMtx);
|
||||
node++;
|
||||
}
|
||||
|
||||
mpAlloc = alloc;
|
||||
return true;
|
||||
}
|
||||
|
||||
void mdl_c::mdlCallback_c::remove() {
|
||||
mCalcRatio.remove();
|
||||
if (mpNodes != nullptr) {
|
||||
// Probably an m_allocator inline
|
||||
MEMFreeToAllocator(mpAlloc, mpNodes);
|
||||
}
|
||||
mpNodes = nullptr;
|
||||
mpAlloc = nullptr;
|
||||
}
|
||||
|
||||
void mdl_c::mdlCallback_c::setBlendFrame(f32 frame) {
|
||||
mCalcRatio.set(frame);
|
||||
}
|
||||
void mdl_c::mdlCallback_c::calcBlend() {
|
||||
if (!mCalcRatio.isEnd()) {
|
||||
mCalcRatio.calc();
|
||||
}
|
||||
}
|
||||
|
||||
mdl_c::mdl_c() : mpOwnedCallback(nullptr), mpCallback(nullptr) {}
|
||||
mdl_c::~mdl_c() {
|
||||
remove();
|
||||
}
|
||||
|
||||
bool mdl_c::create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u32 bufferOption, int nView, u32 *pSize) {
|
||||
return create(mdl, nullptr, alloc, bufferOption, nView, pSize);
|
||||
}
|
||||
|
||||
bool mdl_c::create(nw4r::g3d::ResMdl mdl, mdl_c::mdlCallback_c *cb, mAllocator_c *alloc, u32 bufferOption, int nView,
|
||||
u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 tmp1;
|
||||
u32 tmp2;
|
||||
u32 *pSize1 = nullptr;
|
||||
u32 *pSize2 = nullptr;
|
||||
if (pSize != nullptr) {
|
||||
pSize1 = &tmp1;
|
||||
pSize2 = &tmp2;
|
||||
}
|
||||
|
||||
if (!smdl_c::create(mdl, alloc, bufferOption, nView, pSize1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cb == nullptr) {
|
||||
mpOwnedCallback = (mdlCallback_c *)alloc->alloc(sizeof(mdlCallback_c));
|
||||
if (mpOwnedCallback == nullptr) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
new (mpOwnedCallback) mdlCallback_c();
|
||||
mpCallback = mpOwnedCallback;
|
||||
} else {
|
||||
mpCallback = cb;
|
||||
}
|
||||
if (!mpCallback->create(mdl, alloc, pSize2)) {
|
||||
remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pSize != nullptr) {
|
||||
*pSize = tmp1 + tmp2;
|
||||
}
|
||||
nw4r::g3d::ScnMdlSimple *sMdl;
|
||||
sMdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
|
||||
sMdl->SetCalcWorldCallback(mpCallback);
|
||||
sMdl->EnableScnMdlCallbackTiming(nw4r::g3d::ScnObj::TIMING_ALL);
|
||||
setCallback(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void mdl_c::remove() {
|
||||
if (mpOwnedCallback != nullptr) {
|
||||
mAllocator_c *alloc = mpOwnedCallback->getAllocator();
|
||||
mpOwnedCallback->remove();
|
||||
mpOwnedCallback->~mdlCallback_c();
|
||||
alloc->free(mpOwnedCallback);
|
||||
mpOwnedCallback = nullptr;
|
||||
mpCallback = nullptr;
|
||||
}
|
||||
bmdl_c::remove();
|
||||
}
|
||||
|
||||
void mdl_c::setAnm(m3d::banm_c &anm) {
|
||||
setAnm(anm, 0.0f);
|
||||
}
|
||||
|
||||
void mdl_c::play() {
|
||||
bmdl_c::play();
|
||||
mpCallback->calcBlend();
|
||||
}
|
||||
|
||||
void mdl_c::setAnm(m3d::banm_c &anm, f32 f) {
|
||||
if (anm.getType() == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR) {
|
||||
mpCallback->setBlendFrame(f);
|
||||
}
|
||||
bmdl_c::setAnm(anm);
|
||||
}
|
||||
|
||||
void mdl_c::setCallback(callback_c *cb) {
|
||||
mpCallback->setBaseCallback(cb);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,46 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_proc.h>
|
||||
#include <nw4r/g3d/g3d_scnproc.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
void proc_c_drawProc(nw4r::g3d::ScnProc *proc, bool b) {
|
||||
proc_c *p = static_cast<proc_c *>(proc->GetUserData());
|
||||
if (b) {
|
||||
p->drawOpa();
|
||||
} else {
|
||||
p->drawXlu();
|
||||
}
|
||||
}
|
||||
|
||||
proc_c::~proc_c() {}
|
||||
|
||||
int proc_c::getType() const {
|
||||
return SCN_LEAF_PROC;
|
||||
}
|
||||
|
||||
void proc_c::drawOpa() {}
|
||||
void proc_c::drawXlu() {}
|
||||
|
||||
bool proc_c::create(mAllocator_c *alloc, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 size;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &size;
|
||||
}
|
||||
|
||||
mpScnLeaf = nw4r::g3d::ScnProc::Construct(alloc, pSize, proc_c_drawProc, true, true, 0);
|
||||
if (!mpScnLeaf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mpScnLeaf->SetPriorityDrawOpa(0x7f);
|
||||
mpScnLeaf->SetPriorityDrawXlu(0x7f);
|
||||
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnProc>(mpScnLeaf)->SetUserData(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,108 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_scnleaf.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
scnLeaf_c::scnLeaf_c() : mpScnLeaf(nullptr) {}
|
||||
|
||||
scnLeaf_c::~scnLeaf_c() {
|
||||
scnLeaf_c::remove();
|
||||
}
|
||||
|
||||
void scnLeaf_c::remove() {
|
||||
if (mpScnLeaf != nullptr) {
|
||||
mpScnLeaf->Destroy();
|
||||
mpScnLeaf = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int scnLeaf_c::entry() {
|
||||
return pushBack(mpScnLeaf);
|
||||
}
|
||||
|
||||
void scnLeaf_c::setOption(u32 flag, u32 set) {
|
||||
mpScnLeaf->SetScnObjOption(flag, set);
|
||||
}
|
||||
|
||||
void scnLeaf_c::setScale(f32 x, f32 y, f32 z) {
|
||||
mpScnLeaf->SetScale(x, y, z);
|
||||
}
|
||||
|
||||
void scnLeaf_c::setScale(const nw4r::math::VEC3 &scale) {
|
||||
mpScnLeaf->SetScale(scale);
|
||||
}
|
||||
|
||||
void scnLeaf_c::getScale(nw4r::math::VEC3 *vec) const {
|
||||
mpScnLeaf->GetScale(vec);
|
||||
}
|
||||
|
||||
void scnLeaf_c::setLocalMtx(const nw4r::math::MTX34 *mtx) {
|
||||
mpScnLeaf->SetMtx(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL, mtx);
|
||||
}
|
||||
|
||||
void scnLeaf_c::getLocalMtx(nw4r::math::MTX34 *mtx) const {
|
||||
mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL, mtx);
|
||||
}
|
||||
|
||||
const nw4r::math::MTX34 *scnLeaf_c::getLocalMtx() const {
|
||||
return mpScnLeaf->GetMtxPtr(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL);
|
||||
}
|
||||
|
||||
void scnLeaf_c::getWorldMtx(nw4r::math::MTX34 *mtx) const {
|
||||
mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_WORLD, mtx);
|
||||
}
|
||||
|
||||
void scnLeaf_c::getViewMtx(nw4r::math::MTX34 *mtx) const {
|
||||
mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_VIEW, mtx);
|
||||
}
|
||||
|
||||
// unofficial
|
||||
void scnLeaf_c::setCallback(nw4r::g3d::IScnObjCallback *cb) {
|
||||
mpScnLeaf->SetCallback(cb);
|
||||
}
|
||||
|
||||
nw4r::g3d::IScnObjCallback *scnLeaf_c::swapCallback(nw4r::g3d::IScnObjCallback *cb) {
|
||||
nw4r::g3d::IScnObjCallback *tmp = mpScnLeaf->GetScnObjCallback();
|
||||
mpScnLeaf->SetCallback(cb);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void scnLeaf_c::enableCallbackTiming(nw4r::g3d::ScnObj::Timing timing) {
|
||||
mpScnLeaf->EnableScnObjCallbackTiming(timing);
|
||||
}
|
||||
|
||||
void scnLeaf_c::enableCallbackOp(nw4r::g3d::ScnObj::ExecOp op) {
|
||||
mpScnLeaf->EnableScnObjCallbackExecOp(op);
|
||||
}
|
||||
|
||||
void scnLeaf_c::calc(bool b) {
|
||||
setOption(/* DISABLE_CALC_WORLD */ 0x02, false);
|
||||
mpScnLeaf->G3dProc(1, 0, nullptr);
|
||||
if (b == false) {
|
||||
setOption(/* DISABLE_CALC_WORLD */ 0x02, true);
|
||||
}
|
||||
}
|
||||
|
||||
void scnLeaf_c::calcVtx(bool b) {
|
||||
setOption(/* DISABLE_CALC_VTX */ 0x04, false);
|
||||
mpScnLeaf->G3dProc(3, 0, nullptr);
|
||||
if (b == false) {
|
||||
setOption(/* DISABLE_CALC_VTX */ 0x04, true);
|
||||
}
|
||||
}
|
||||
|
||||
/** Unknown name/arg type */
|
||||
void scnLeaf_c::calcView(void *p, bool b) {
|
||||
setOption(/* DISABLE_CALC_VIEW */ 0x05, false);
|
||||
mpScnLeaf->G3dProc(4, 0, p);
|
||||
if (b == false) {
|
||||
setOption(/* DISABLE_CALC_VIEW */ 0x05, true);
|
||||
}
|
||||
}
|
||||
|
||||
void scnLeaf_c::setPriorityDraw(int opa, int xlu) {
|
||||
mpScnLeaf->SetPriorityDrawOpa(opa);
|
||||
mpScnLeaf->SetPriorityDrawXlu(xlu);
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <m/m3d/m_smdl.h>
|
||||
#include <nw4r/g3d/g3d_scnmdl.h>
|
||||
#include <nw4r/g3d/g3d_scnmdlsmpl.h>
|
||||
|
||||
namespace m3d {
|
||||
|
||||
smdl_c::smdl_c() {}
|
||||
smdl_c::~smdl_c() {}
|
||||
|
||||
bool smdl_c::create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u32 bufferOption, int nView, u32 *pSize) {
|
||||
if (alloc == nullptr) {
|
||||
alloc = internal::l_allocator_p;
|
||||
}
|
||||
|
||||
u32 tmp;
|
||||
if (pSize == nullptr) {
|
||||
pSize = &tmp;
|
||||
}
|
||||
|
||||
if (bufferOption != 0) {
|
||||
mpScnLeaf = nw4r::g3d::ScnMdl::Construct(alloc, pSize, mdl, bufferOption, nView);
|
||||
} else {
|
||||
mpScnLeaf = nw4r::g3d::ScnMdlSimple::Construct(alloc, pSize, mdl, nView);
|
||||
}
|
||||
|
||||
if (mpScnLeaf == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mpScnLeaf->SetPriorityDrawOpa(0x7f);
|
||||
mpScnLeaf->SetPriorityDrawXlu(0x7f);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace m3d
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <d/d_system.h>
|
||||
#include <m/m_video.h>
|
||||
|
||||
// I dont know if this file actually exists, the place that the function exists is in an odd spot
|
||||
|
||||
namespace mVideo {
|
||||
|
||||
// 0x80065590
|
||||
void create() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // namespace mVideo
|
||||
@@ -99,6 +99,6 @@ void mHeapAllocator_c::adjustFrmHeapRestoreCurrent() {
|
||||
mHeap::adjustFrmHeap(static_cast<EGG::FrmHeap *>(getHeapOfKind(heap, EGG::Heap::HEAP_KIND_FRAME)));
|
||||
}
|
||||
|
||||
void *mHeapAllocator_c::allocOnHeap(u32 size, mHeapAllocator_c *allocator) {
|
||||
void *operator new[](size_t size, mAllocator_c *allocator) {
|
||||
return allocator->alloc(size);
|
||||
}
|
||||
|
||||
+4
-7
@@ -1,13 +1,10 @@
|
||||
#include <m/m_fader.h>
|
||||
|
||||
// nw4r::g3d::G3DState::Invalidate
|
||||
extern "C" void fn_8044E3B0(u32 flags);
|
||||
// m3d::resetMaterial according to NSMBW
|
||||
extern "C" void fn_802E46D0();
|
||||
#include <m/m3d/m3d.h>
|
||||
#include <nw4r/g3d/g3d_state.h>
|
||||
|
||||
void mFader_c::draw() {
|
||||
fn_8044E3B0(0x7ff);
|
||||
fn_802E46D0();
|
||||
nw4r::g3d::G3DState::Invalidate(0x7ff);
|
||||
m3d::resetMaterial();
|
||||
mpFader->draw();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user