mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-10-26 13:56:05 +03:00
feat(model): implement CM2Model::AttachToParent
This commit is contained in:
parent
03cb7e699e
commit
6780f5061f
@ -8,7 +8,7 @@
|
||||
int32_t CCharacterCreation::m_selectedClassID;
|
||||
int32_t CCharacterCreation::m_existingCharacterIndex;
|
||||
int32_t CCharacterCreation::m_raceIndex;
|
||||
CSimpleModel* CCharacterCreation::m_charCustomizeFrame;
|
||||
CSimpleModelFFX* CCharacterCreation::m_charCustomizeFrame;
|
||||
float CCharacterCreation::m_charFacing;
|
||||
uint32_t CCharacterCreation::m_prevSkinIndex;
|
||||
uint32_t CCharacterCreation::m_prevFaceIndex;
|
||||
@ -66,7 +66,7 @@ void CCharacterCreation::Initialize() {
|
||||
} while (weirdCondition || factionSwitch == 1);
|
||||
}
|
||||
|
||||
void CCharacterCreation::SetCharCustomizeFrame(CSimpleModel* frame) {
|
||||
void CCharacterCreation::SetCharCustomizeFrame(CSimpleModelFFX* frame) {
|
||||
CCharacterCreation::m_charCustomizeFrame = frame;
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ class CCharacterCreation {
|
||||
static int32_t m_selectedClassID;
|
||||
static int32_t m_existingCharacterIndex;
|
||||
static int32_t m_raceIndex;
|
||||
static CSimpleModel* m_charCustomizeFrame;
|
||||
static CSimpleModelFFX* m_charCustomizeFrame;
|
||||
static float m_charFacing;
|
||||
static uint32_t m_prevSkinIndex;
|
||||
static uint32_t m_prevFaceIndex;
|
||||
@ -40,7 +40,7 @@ class CCharacterCreation {
|
||||
|
||||
// Static functions
|
||||
static void Initialize();
|
||||
static void SetCharCustomizeFrame(CSimpleModel* frame);
|
||||
static void SetCharCustomizeFrame(CSimpleModelFFX* frame);
|
||||
static void SetCharCustomizeModel(char const* filename);
|
||||
static void ResetCharCustomizeInfo();
|
||||
static void GetRandomRaceAndSex(ComponentData* data);
|
||||
|
||||
@ -24,8 +24,7 @@ CM2Model* CM2Model::AllocModel(uint32_t* heapId) {
|
||||
if (ObjectAlloc(*heapId, &memHandle, &object, 0)) {
|
||||
CM2Model* model = new (object) CM2Model();
|
||||
|
||||
// TODO
|
||||
// model->uint2E8 = memHandle;
|
||||
model->m_handle = memHandle;
|
||||
|
||||
return model;
|
||||
}
|
||||
@ -587,6 +586,167 @@ void CM2Model::AttachToScene(CM2Scene* scene) {
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t CM2Model::AttachToParent(CM2Model* parent, uint32_t attachmentId, const C3Vector* a4, int32_t a5) {
|
||||
if (this->m_attachParent) {
|
||||
this->DetachFromParent();
|
||||
}
|
||||
|
||||
this->SetAnimating(0);
|
||||
|
||||
uint16_t attachmentIndex = 0xFFFF;
|
||||
|
||||
if (parent->m_loaded) {
|
||||
if (attachmentId < parent->m_shared->m_data->attachmentIndicesById.Count()) {
|
||||
attachmentIndex = parent->m_shared->m_data->attachmentIndicesById[attachmentId];
|
||||
}
|
||||
|
||||
if (attachmentIndex == 0xFFFF && !a5) {
|
||||
return attachmentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
this->m_attachmentIndex = attachmentIndex;
|
||||
this->m_attachmentId = attachmentId;
|
||||
this->m_attachParent = parent;
|
||||
|
||||
if (a5) {
|
||||
this->f_flags = this->f_flags ^ (this->f_flags ^ (1 << 18)) & 0x40000 | 0x20080;
|
||||
} else {
|
||||
this->f_flags = this->f_flags ^ (this->f_flags ^ 0) & 0x40000 | 0x20080;
|
||||
}
|
||||
|
||||
this->m_attachmentPrev = &parent->m_attachmentBase;
|
||||
this->m_attachmentNext = parent->m_attachmentBase;
|
||||
if (parent->m_attachmentBase) {
|
||||
parent->m_attachmentBase->m_attachmentPrev = &this->m_attachmentNext;
|
||||
}
|
||||
parent->m_attachmentBase = this;
|
||||
|
||||
if (!this->m_loaded || !this->m_flag100) {
|
||||
auto model = parent;
|
||||
while (parent) {
|
||||
model->f_flags &= ~0x100u;
|
||||
model = model->m_attachParent;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->m_flag2) {
|
||||
auto model = parent;
|
||||
while (parent) {
|
||||
model->f_flags &= ~0x200u;
|
||||
model = model->m_attachParent;
|
||||
}
|
||||
}
|
||||
|
||||
if (a4 && this->m_attachParent && this->m_attachParent->m_loaded && this->m_attachmentIndex != 0xFFFF) {
|
||||
auto transform = parent->GetAttachmentWorldTransform(attachmentId);
|
||||
|
||||
float v12 = sqrt(transform.a0 * transform.a0 + transform.a1 * transform.a1 + transform.a2 * transform.a2);
|
||||
// WRAP: C44Matrix__AffineInvertInPlace below
|
||||
if (fabs(v12 - 1.0f) >= 0.00000095367432) {
|
||||
float v5[3][3];
|
||||
v5[0][0] = transform.a0;
|
||||
v5[0][1] = transform.a1;
|
||||
v5[0][2] = transform.a2;
|
||||
v5[1][0] = transform.b0;
|
||||
v5[1][1] = transform.b1;
|
||||
v5[1][2] = transform.b2;
|
||||
v5[2][0] = transform.c0;
|
||||
v5[2][1] = transform.c1;
|
||||
v5[2][2] = transform.c2;
|
||||
|
||||
float v8[3][3];
|
||||
v8[0][0] = v5[0][0];
|
||||
v8[0][1] = v5[1][0];
|
||||
v8[0][2] = v5[2][0];
|
||||
v8[1][0] = v5[0][1];
|
||||
v8[1][1] = v5[1][1];
|
||||
v8[1][2] = v5[2][1];
|
||||
v8[2][0] = v5[0][2];
|
||||
v8[2][1] = v5[1][2];
|
||||
v8[2][2] = v5[2][2];
|
||||
|
||||
C44Matrix matrix;
|
||||
matrix.a0 = v8[0][0];
|
||||
matrix.a1 = v8[0][1];
|
||||
matrix.a2 = v8[0][2];
|
||||
matrix.a3 = 0.0f;
|
||||
matrix.b0 = v8[1][0];
|
||||
matrix.b1 = v8[1][1];
|
||||
matrix.b2 = v8[1][2];
|
||||
matrix.b3 = 0.0f;
|
||||
matrix.c0 = v8[2][0];
|
||||
matrix.c1 = v8[2][1];
|
||||
matrix.c2 = v8[2][2];
|
||||
matrix.c3 = 0.0f;
|
||||
matrix.d0 = 0.0f;
|
||||
matrix.d1 = 0.0f;
|
||||
matrix.d2 = 0.0f;
|
||||
matrix.d3 = 1.0f;
|
||||
|
||||
matrix.Scale(1.0f / (v12 * v12));
|
||||
matrix.Translate(C3Vector(-transform.d0, -transform.d1, -transform.d2));
|
||||
transform = matrix;
|
||||
} else {
|
||||
float v5[3][3];
|
||||
v5[0][0] = transform.a0;
|
||||
v5[0][1] = transform.a1;
|
||||
v5[0][2] = transform.a2;
|
||||
v5[1][0] = transform.b0;
|
||||
v5[1][1] = transform.b1;
|
||||
v5[1][2] = transform.b2;
|
||||
v5[2][0] = transform.c0;
|
||||
v5[2][1] = transform.c1;
|
||||
v5[2][2] = transform.c2;
|
||||
|
||||
float v8[3][3];
|
||||
v8[0][0] = v5[0][0];
|
||||
v8[0][1] = v5[1][0];
|
||||
v8[0][2] = v5[2][0];
|
||||
v8[1][0] = v5[0][1];
|
||||
v8[1][1] = v5[1][1];
|
||||
v8[1][2] = v5[2][1];
|
||||
v8[2][0] = v5[0][2];
|
||||
v8[2][1] = v5[1][2];
|
||||
v8[2][2] = v5[2][2];
|
||||
|
||||
C44Matrix matrix;
|
||||
matrix.a0 = v8[0][0];
|
||||
matrix.a1 = v8[0][1];
|
||||
matrix.a2 = v8[0][2];
|
||||
matrix.a3 = 0.0f;
|
||||
matrix.b0 = v8[1][0];
|
||||
matrix.b1 = v8[1][1];
|
||||
matrix.b2 = v8[1][2];
|
||||
matrix.b3 = 0.0f;
|
||||
matrix.c0 = v8[2][0];
|
||||
matrix.c1 = v8[2][1];
|
||||
matrix.c2 = v8[2][2];
|
||||
matrix.c3 = 0.0f;
|
||||
matrix.d0 = 0.0f;
|
||||
matrix.d1 = 0.0f;
|
||||
matrix.d2 = 0.0f;
|
||||
matrix.d3 = 1.0f;
|
||||
|
||||
matrix.Translate(C3Vector(-transform.d0, -transform.d1, -transform.d2));
|
||||
transform = matrix;
|
||||
}
|
||||
|
||||
if (!this->m_flag8000) {
|
||||
this->matrixB4 = C44Matrix();
|
||||
}
|
||||
|
||||
transform.Translate(*a4);
|
||||
|
||||
this->matrixB4.d0 = transform.a0;
|
||||
this->matrixB4.d1 = transform.a1;
|
||||
this->matrixB4.d2 = transform.a2;
|
||||
this->m_flag8000 = 1;
|
||||
}
|
||||
|
||||
++this->m_refCount;
|
||||
}
|
||||
|
||||
void CM2Model::CancelDeferredSequences(uint32_t boneIndex, bool a3) {
|
||||
// TODO
|
||||
}
|
||||
@ -595,6 +755,41 @@ void CM2Model::DetachFromScene() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CM2Model::DetachFromParent() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
C44Matrix CM2Model::GetAttachmentWorldTransform(uint32_t attachmentId) {
|
||||
if (!this->m_loaded) {
|
||||
this->WaitForLoad(nullptr);
|
||||
}
|
||||
|
||||
uint16_t attachmentIndex = 0xFFFF;
|
||||
|
||||
auto data = this->m_shared->m_data;
|
||||
if (attachmentId < data->attachmentIndicesById.Count()) {
|
||||
attachmentIndex = data->attachmentIndicesById[attachmentId];
|
||||
}
|
||||
|
||||
uint16_t boneIndex = 0xFFFF;
|
||||
if (attachmentIndex < data->attachments.Count()) {
|
||||
boneIndex = data->attachments[attachmentIndex].boneIndex;
|
||||
}
|
||||
|
||||
this->Animate();
|
||||
|
||||
C44Matrix matrix;
|
||||
|
||||
if (attachmentIndex == 0xFFFF) {
|
||||
matrix = this->m_boneMatrices[0];
|
||||
} else {
|
||||
matrix = this->m_boneMatrices[boneIndex];
|
||||
matrix.Translate(data->attachments[attachmentIndex].position);
|
||||
}
|
||||
|
||||
return matrix * this->m_scene->m_viewInv;
|
||||
}
|
||||
|
||||
void CM2Model::FindKey(M2ModelBoneSeq* sequence, const M2TrackBase& track, uint32_t& currentKey, uint32_t& nextKey, float& ratio) {
|
||||
if (!track.sequenceTimes.Count()) {
|
||||
nextKey = 0;
|
||||
|
||||
@ -47,29 +47,34 @@ class CM2Model {
|
||||
uint32_t m_flags = 0;
|
||||
CM2Model** m_scenePrev = nullptr;
|
||||
CM2Model* m_sceneNext = nullptr;
|
||||
uint32_t m_loaded : 1;
|
||||
uint32_t m_flag2 : 1;
|
||||
uint32_t m_flag4 : 1;
|
||||
uint32_t m_flag8 : 1;
|
||||
uint32_t m_flag10 : 1;
|
||||
uint32_t m_flag20 : 1;
|
||||
uint32_t m_flag40 : 1;
|
||||
uint32_t m_flag80 : 1;
|
||||
uint32_t m_flag100 : 1;
|
||||
uint32_t m_flag200 : 1;
|
||||
uint32_t m_flag400 : 1;
|
||||
uint32_t m_flag800 : 1;
|
||||
uint32_t m_flag1000 : 1;
|
||||
uint32_t m_flag2000 : 1;
|
||||
uint32_t m_flag4000 : 1;
|
||||
uint32_t m_flag8000 : 1;
|
||||
uint32_t m_flag10000 : 1;
|
||||
uint32_t m_flag20000 : 1;
|
||||
uint32_t m_flag40000 : 1;
|
||||
uint32_t m_flag80000 : 1;
|
||||
uint32_t m_flag100000 : 1;
|
||||
uint32_t m_flag200000 : 1;
|
||||
uint32_t m_flag400000 : 1;
|
||||
union {
|
||||
struct {
|
||||
uint32_t m_loaded : 1;
|
||||
uint32_t m_flag2 : 1;
|
||||
uint32_t m_flag4 : 1;
|
||||
uint32_t m_flag8 : 1;
|
||||
uint32_t m_flag10 : 1;
|
||||
uint32_t m_flag20 : 1;
|
||||
uint32_t m_flag40 : 1;
|
||||
uint32_t m_flag80 : 1;
|
||||
uint32_t m_flag100 : 1;
|
||||
uint32_t m_flag200 : 1;
|
||||
uint32_t m_flag400 : 1;
|
||||
uint32_t m_flag800 : 1;
|
||||
uint32_t m_flag1000 : 1;
|
||||
uint32_t m_flag2000 : 1;
|
||||
uint32_t m_flag4000 : 1;
|
||||
uint32_t m_flag8000 : 1;
|
||||
uint32_t m_flag10000 : 1;
|
||||
uint32_t m_flag20000 : 1;
|
||||
uint32_t m_flag40000 : 1;
|
||||
uint32_t m_flag80000 : 1;
|
||||
uint32_t m_flag100000 : 1;
|
||||
uint32_t m_flag200000 : 1;
|
||||
uint32_t m_flag400000 : 1;
|
||||
};
|
||||
uint32_t f_flags;
|
||||
};
|
||||
CM2Model** m_callbackPrev = nullptr;
|
||||
CM2Model* m_callbackNext = nullptr;
|
||||
void (*m_loadedCallback)(CM2Model*, void*) = nullptr;
|
||||
@ -82,6 +87,11 @@ class CM2Model {
|
||||
CM2Model** m_animatePrev = nullptr;
|
||||
CM2Model* m_animateNext = nullptr;
|
||||
CM2Model* m_attachParent = nullptr;
|
||||
uint32_t m_attachmentId;
|
||||
uint16_t m_attachmentIndex;
|
||||
CM2Model* m_attachmentBase = nullptr;
|
||||
CM2Model** m_attachmentPrev = nullptr;
|
||||
CM2Model* m_attachmentNext = nullptr;
|
||||
uint32_t m_time = 0;
|
||||
CM2Model** m_drawPrev = nullptr;
|
||||
CM2Model* m_drawNext = nullptr;
|
||||
@ -108,6 +118,7 @@ class CM2Model {
|
||||
void* m_lightingArg = nullptr;
|
||||
M2ModelCamera* m_cameras = nullptr;
|
||||
void* ptr2D0 = nullptr;
|
||||
uint32_t m_handle = 0;
|
||||
|
||||
// Member functions
|
||||
CM2Model()
|
||||
@ -141,8 +152,11 @@ class CM2Model {
|
||||
void AnimateMTSimple(const C44Matrix* view, const C3Vector& a3, const C3Vector& a4, float a5, float a6);
|
||||
void AnimateST();
|
||||
void AttachToScene(CM2Scene* scene);
|
||||
uint16_t AttachToParent(CM2Model* parent, uint32_t attachmentId, const C3Vector* a4, int32_t a5);
|
||||
void CancelDeferredSequences(uint32_t boneIndex, bool a3);
|
||||
void DetachFromScene();
|
||||
void DetachFromParent();
|
||||
C44Matrix GetAttachmentWorldTransform(uint32_t attachmentId);
|
||||
void FindKey(M2ModelBoneSeq* sequence, const M2TrackBase& track, uint32_t& currentKey, uint32_t& nextKey, float& ratio);
|
||||
CAaBox& GetBoundingBox(CAaBox& bounds);
|
||||
HCAMERA GetCameraByIndex(uint32_t index);
|
||||
|
||||
@ -23,7 +23,7 @@ int32_t Script_SetCharCustomizeFrame(lua_State* L) {
|
||||
auto frame = CScriptObject::GetScriptObjectByName(name, type);
|
||||
|
||||
if (frame) {
|
||||
CCharacterCreation::SetCharCustomizeFrame(static_cast<CSimpleModel*>(frame));
|
||||
CCharacterCreation::SetCharCustomizeFrame(static_cast<CSimpleModelFFX*>(frame));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user