Anim presenters (#1719)
Some checks are pending
Analyze / ${{ matrix.who }} annotations (CONFIG) (push) Waiting to run
Analyze / ${{ matrix.who }} annotations (ISLE) (push) Waiting to run
Analyze / ${{ matrix.who }} annotations (LEGO1) (push) Waiting to run
Build / Download original binaries (push) Waiting to run
Build / Current ${{ matrix.toolchain.name }} (map[clang-tidy:true msys-env:mingw-w64-i686 msystem:mingw32 name:msys2 mingw32 shell:msys2 {0} werror:true]) (push) Waiting to run
Build / Current ${{ matrix.toolchain.name }} (map[name:MSVC setup-cmake:true setup-msvc:true setup-ninja:true shell:sh]) (push) Waiting to run
Build / MSVC 4.20 (push) Waiting to run
Build / MSVC 4.20 (BETA10) (push) Waiting to run
Build / Verify decomp (push) Blocked by required conditions
Build / Upload artifacts (push) Blocked by required conditions
Format / C++ (push) Waiting to run
Naming / C++ (push) Waiting to run

* Clear unknowns in `LegoAnimPresenter`, `LegoLocomotionAnimPresenter` and `LegoHideAnimPresenter`

* Clear visibility unknowns in animation presenters

---------

Co-authored-by: Florian Kaiser <mail@floriankaiser.org>
Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
Fabian Neundorf 2026-01-13 21:54:44 +01:00 committed by GitHub
parent dace101b85
commit 600079215f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 309 additions and 295 deletions

View File

@ -62,21 +62,27 @@ class LegoAnimPresenter : public MxVideoPresenter {
return !strcmp(p_name, LegoAnimPresenter::ClassName()) || MxVideoPresenter::IsA(p_name);
}
void ReadyTickle() override; // vtable+0x18
void StartingTickle() override; // vtable+0x1c
void StreamingTickle() override; // vtable+0x20
void DoneTickle() override; // vtable+0x2c
void ParseExtra() override; // vtable+0x30
MxResult AddToManager() override; // vtable+0x34
void Destroy() override; // vtable+0x38
MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
virtual MxResult CreateAnim(MxStreamChunk* p_chunk); // vtable+0x88
virtual void VTable0x8c(); // vtable+0x8c
virtual void VTable0x90(); // vtable+0x90
virtual MxU32 VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3); // vtable+0x94
virtual MxResult VTable0x98(LegoPathBoundary* p_boundary); // vtable+0x98
void ReadyTickle() override; // vtable+0x18
void StartingTickle() override; // vtable+0x1c
void StreamingTickle() override; // vtable+0x20
void DoneTickle() override; // vtable+0x2c
void ParseExtra() override; // vtable+0x30
MxResult AddToManager() override; // vtable+0x34
void Destroy() override; // vtable+0x38
MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
virtual MxResult CreateAnim(MxStreamChunk* p_chunk); // vtable+0x88
virtual void AddToWorld(); // vtable+0x8c
virtual void RemoveFromWorld(); // vtable+0x90
virtual MxU32 Intersect(
Vector3& p_rayOrigin,
Vector3& p_rayDirection,
float p_rayLength,
float p_radius,
Vector3& p_intersectionPoint
); // vtable+0x94
virtual MxResult AddActors(LegoPathBoundary* p_boundary); // vtable+0x98
// FUNCTION: LEGO1 0x1000c990
virtual LegoROI** GetROIMap(MxU32& p_roiMapSize)
@ -85,47 +91,47 @@ class LegoAnimPresenter : public MxVideoPresenter {
return m_roiMap;
} // vtable+0x9c
virtual void VTable0xa0(Matrix4& p_matrix); // vtable+0xa0
virtual void SetTransform(Matrix4& p_matrix); // vtable+0xa0
MxResult FUN_1006afc0(MxMatrix*& p_matrix, float p_und);
MxResult FUN_1006b140(LegoROI* p_roi);
void FUN_1006c7a0();
MxResult GetTransforms(MxMatrix*& p_matrix, float p_time);
MxResult CopyTransform(LegoROI* p_roi);
void ApplyFinishedTransform();
const char* GetActionObjectName();
void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; }
// FUNCTION: BETA10 0x1005aad0
void SetUnknown0x0cTo1() { m_unk0x9c = 1; }
void SetRoiTransformApplied() { m_roiTransformApplied = 1; }
// FUNCTION: BETA10 0x1005ab00
void SetUnknown0xa0(Matrix4* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; }
void SetRoiTransform(Matrix4* p_roiTransform) { m_roiTransform = p_roiTransform; }
LegoAnim* GetAnimation() { return m_anim; }
protected:
void Init();
void Destroy(MxBool p_fromDestructor);
LegoChar* FUN_10069150(const LegoChar* p_und1);
void FUN_100692b0();
void FUN_100695c0();
LegoChar* GetActorName(const LegoChar* p_name);
void CreateManagedActors();
void CreateSceneROIs();
LegoChar* GetVariableOrIdentity(const LegoChar* p_varName, const LegoChar* p_prefix);
LegoBool FUN_100698b0(const CompoundObject& p_rois, const LegoChar* p_und2);
LegoBool AppendROIToScene(const CompoundObject& p_rois, const LegoChar* p_varName);
LegoROI* FindROI(const LegoChar* p_name);
void FUN_10069b10();
void BuildROIMap();
void UpdateStructMapAndROIIndex(LegoAnimStructMap& p_map, LegoTreeNode* p_node, LegoROI* p_roi);
void UpdateStructMapAndROIIndexForNode(
LegoAnimStructMap& p_map,
LegoAnimNodeData* p_data,
const LegoChar* p_und,
const LegoChar* p_key,
LegoROI* p_roi
);
void FUN_1006aa60();
void FUN_1006ab70();
LegoBool FUN_1006aba0();
MxBool FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi);
void ReleaseManagedActors();
void AppendManagedActors();
LegoBool VerifyAnimationTree();
MxBool VerifyAnimationNode(LegoTreeNode* p_node, LegoROI* p_roi);
void SubstituteVariables();
void FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
void FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
void ApplyTransform(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
void ApplyTransformWithVisibilityAndCam(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
void SetDisabled(MxBool p_disabled);
LegoAnim* m_anim; // 0x64
@ -133,27 +139,27 @@ class LegoAnimPresenter : public MxVideoPresenter {
MxU32 m_roiMapSize; // 0x6c
LegoROIList* m_sceneROIs; // 0x70
LegoROIList* m_managedActors; // 0x74
Matrix4* m_unk0x78; // 0x78
Matrix4* m_transform; // 0x78
MxU32 m_flags; // 0x7c
LegoWorld* m_currentWorld; // 0x80
MxAtomId m_worldAtom; // 0x84
MxS32 m_worldId; // 0x88
LegoROI** m_unk0x8c; // 0x8c
char** m_unk0x90; // 0x90
MxU8 m_unk0x94; // 0x94
MxBool m_unk0x95; // 0x95
MxBool m_unk0x96; // 0x96
LegoROI** m_ptAtCamROI; // 0x8c
char** m_ptAtCamNames; // 0x90
MxU8 m_ptAtCamCount; // 0x94
MxBool m_animationFinished; // 0x95
MxBool m_localActors; // 0x96
undefined m_unk0x97; // 0x97
LegoAnimSubstMap* m_substMap; // 0x98
MxS16 m_unk0x9c; // 0x9c
Matrix4* m_unk0xa0; // 0xa0
MxS16 m_roiTransformApplied; // 0x9c
Matrix4* m_roiTransform; // 0xa0
// SYNTHETIC: LEGO1 0x10068650
// LegoAnimPresenter::`scalar deleting destructor'
public:
float m_unk0xa4; // 0xa4
Mx3DPointFloat m_unk0xa8; // 0xa8
float m_boundingRadius; // 0xa4
Mx3DPointFloat m_centerPoint; // 0xa8
};
// VTABLE: LEGO1 0x100d4900
@ -231,16 +237,16 @@ class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter {
void PutFrame() override; // vtable+0x6c
MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88
void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value);
void CreateROIAndBuildMap(LegoAnimActor* p_actor, MxFloat p_worldSpeed);
void DecrementUnknown0xd4()
void DecrementWorldRefCounter()
{
if (m_unk0xd4) {
--m_unk0xd4;
if (m_worldRefCounter) {
--m_worldRefCounter;
}
}
undefined2 GetUnknown0xd4() { return m_unk0xd4; }
MxS16 GetWorldRefCounter() { return m_worldRefCounter; }
// SYNTHETIC: LEGO1 0x1006cfe0
// LegoLocomotionAnimPresenter::`scalar deleting destructor'
@ -254,7 +260,7 @@ class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter {
LegoROIMapList* m_roiMapList; // 0xc8
MxS32 m_unk0xcc; // 0xcc
MxS32 m_unk0xd0; // 0xd0
undefined2 m_unk0xd4; // 0xd4
MxS16 m_worldRefCounter; // 0xd4
};
class LegoPathBoundary;
@ -279,10 +285,10 @@ class LegoHideAnimPresenter : public LegoLoopingAnimPresenter {
~LegoHideAnimPresenter() override;
// FUNCTION: LEGO1 0x1006d860
void VTable0x8c() override {} // vtable+0x8c
void AddToWorld() override {} // vtable+0x8c
// FUNCTION: LEGO1 0x1006d870
void VTable0x90() override {} // vtable+0x90
void RemoveFromWorld() override {} // vtable+0x90
// FUNCTION: BETA10 0x1005d4a0
static const char* HandlerClassName()
@ -311,7 +317,7 @@ class LegoHideAnimPresenter : public LegoLoopingAnimPresenter {
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
void FUN_1006db40(LegoTime p_time);
void ApplyVisibility(LegoTime p_time);
// SYNTHETIC: LEGO1 0x1006d9d0
// LegoHideAnimPresenter::`scalar deleting destructor'
@ -319,10 +325,10 @@ class LegoHideAnimPresenter : public LegoLoopingAnimPresenter {
private:
void Init();
void Destroy(MxBool p_fromDestructor);
void FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time);
void FUN_1006dc10();
void FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node);
void FUN_1006e470(
void ApplyVisibility(LegoTreeNode* p_node, LegoTime p_time);
void AssignIndiciesWithMap();
void BuildMap(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node);
void CheckedAdd(
LegoHideAnimStructMap& p_map,
LegoAnimNodeData* p_data,
const char* p_name,

View File

@ -1216,7 +1216,7 @@ void Act3Shark::ParseAction(char* p_extra)
token = strtok(NULL, g_parseExtraTokens);
if (token != NULL) {
presenter->FUN_1006d680(this, atof(token));
presenter->CreateROIAndBuildMap(this, atof(token));
}
}

View File

@ -70,7 +70,7 @@ void Doors::Animate(float p_time)
assert(m_ltDoor && m_rtDoor);
// TODO: Match
m_roi->SetVisibility(m_boundary->GetFlag0x10());
m_roi->SetVisibility(m_boundary->GetVisibility());
switch (m_state) {
case e_none:

View File

@ -121,7 +121,7 @@ void LegoCarBuildAnimPresenter::PutFrame()
MoveShelfForward();
case e_stopped:
if (m_carBuildEntity->GetROI()) {
FUN_1006b9a0(m_anim, m_shelfFrameBuffer, NULL);
ApplyTransformWithVisibilityAndCam(m_anim, m_shelfFrameBuffer, NULL);
}
default:
break;
@ -589,7 +589,7 @@ void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle)
m_platformAnimNodeData->GetRotationKey(0)->SetAngle(newRotation[3]);
if (m_carBuildEntity->GetROI()) {
FUN_1006b9a0(&m_platformAnim, m_shelfFrameBuffer, NULL);
ApplyTransformWithVisibilityAndCam(&m_platformAnim, m_shelfFrameBuffer, NULL);
}
}
}

View File

@ -2384,7 +2384,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_
presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC);
if (presenter != NULL) {
presenter->FUN_1006d680(p_actor, 1.7f);
presenter->CreateROIAndBuildMap(p_actor, 1.7f);
}
g_vehicles[g_characters[p_characterId].m_vehicleId].m_unk0x04 = FALSE;
@ -2397,7 +2397,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_
presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC);
if (presenter != NULL) {
presenter->FUN_1006d680(p_actor, 0.7f);
presenter->CreateROIAndBuildMap(p_actor, 0.7f);
}
}
@ -2410,7 +2410,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_
presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC);
if (presenter != NULL) {
presenter->FUN_1006d680(p_actor, 4.0f);
presenter->CreateROIAndBuildMap(p_actor, 4.0f);
}
}
@ -2423,7 +2423,7 @@ MxBool LegoAnimationManager::FUN_10063b90(LegoWorld* p_world, LegoExtraActor* p_
presenter = (LegoLocomotionAnimPresenter*) p_world->Find("LegoAnimPresenter", vehicleWC);
if (presenter != NULL) {
presenter->FUN_1006d680(p_actor, 0.0f);
presenter->CreateROIAndBuildMap(p_actor, 0.0f);
}
}
@ -2712,12 +2712,12 @@ MxResult LegoAnimationManager::FUN_10064380(
LegoLocomotionAnimPresenter* presenter =
(LegoLocomotionAnimPresenter*) world->Find("LegoAnimPresenter", cycles[p_undIdx1]);
if (presenter != NULL) {
presenter->FUN_1006d680(actor, 0.0f);
presenter->CreateROIAndBuildMap(actor, 0.0f);
}
presenter = (LegoLocomotionAnimPresenter*) world->Find("LegoAnimPresenter", cycles[p_undIdx2]);
if (presenter != NULL) {
presenter->FUN_1006d680(actor, 4.0f);
presenter->CreateROIAndBuildMap(actor, 4.0f);
}
m_extras[i].m_unk0x08 = Timer()->GetTime();

View File

@ -152,7 +152,7 @@ void LegoAnimMMPresenter::ReadyTickle()
}
if (m_tranInfo != NULL && m_tranInfo->m_unk0x0c != NULL) {
m_presenter->VTable0xa0(*m_tranInfo->m_unk0x0c);
m_presenter->SetTransform(*m_tranInfo->m_unk0x0c);
}
if (m_presenter != NULL) {
@ -168,7 +168,7 @@ void LegoAnimMMPresenter::StartingTickle()
{
if (m_presenter == NULL || m_presenter->GetCurrentTickleState() == e_idle) {
if (m_tranInfo != NULL && m_tranInfo->m_unk0x08 != NULL) {
m_presenter->FUN_1006b140(m_tranInfo->m_unk0x08);
m_presenter->CopyTransform(m_tranInfo->m_unk0x08);
}
m_unk0x50 = Timer()->GetTime();
@ -316,7 +316,7 @@ MxBool LegoAnimMMPresenter::FUN_1004b450()
MxBool LegoAnimMMPresenter::FUN_1004b530(MxLong p_time)
{
if (m_presenter != NULL) {
m_presenter->FUN_1006afc0(m_unk0x68, 0);
m_presenter->GetTransforms(m_unk0x68, 0);
m_roiMap = m_presenter->GetROIMap(m_roiMapSize);
m_roiMapSize++;
}
@ -498,7 +498,7 @@ void LegoAnimMMPresenter::FUN_1004b840()
MxDSAction* action = m_action;
if (m_presenter != NULL) {
m_presenter->FUN_1006c7a0();
m_presenter->ApplyFinishedTransform();
}
for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) {

View File

@ -117,8 +117,8 @@ void LegoWorld::Destroy(MxBool p_fromDestructor)
if (presenter->IsA("LegoLocomotionAnimPresenter")) {
LegoLocomotionAnimPresenter* animPresenter = (LegoLocomotionAnimPresenter*) presenter;
animPresenter->DecrementUnknown0xd4();
if (animPresenter->GetUnknown0xd4() == 0) {
animPresenter->DecrementWorldRefCounter();
if (animPresenter->GetWorldRefCounter() == 0) {
ApplyMask(action, MxDSAction::c_world, FALSE);
presenter->EndAction();
}

View File

@ -109,7 +109,7 @@ MxResult LegoAnimActor::AnimateWithTransform(float p_time, Matrix4& p_transform)
LegoROI** roiMap = m_animMaps[m_curAnim]->m_roiMap;
MxU32 numROIs = m_animMaps[m_curAnim]->m_numROIs;
if (!m_boundary->GetFlag0x10()) {
if (!m_boundary->GetVisibility()) {
MxU32 i;
m_roi->SetVisibility(FALSE);
@ -244,7 +244,7 @@ void LegoAnimActor::ParseAction(char* p_extra)
token = strtok(NULL, g_parseExtraTokens);
if (token) {
p->FUN_1006d680(this, atof(token));
p->CreateROIAndBuildMap(this, atof(token));
}
}

View File

@ -166,7 +166,7 @@ inline void LegoExtraActor::InitializeReassemblyAnim()
if (!m_assAnim) {
MxS32 index = 0;
m_assAnimP->FUN_1006d680(this, -20.0f);
m_assAnimP->CreateROIAndBuildMap(this, -20.0f);
for (MxS32 i = 0; i < m_animMaps.size(); i++) {
if (m_animMaps[i]->GetWorldSpeed() == -20.0f) {
@ -178,7 +178,7 @@ inline void LegoExtraActor::InitializeReassemblyAnim()
if (!m_disAnim) {
MxS32 index = 0;
m_disAnimP->FUN_1006d680(this, -21.0f);
m_disAnimP->CreateROIAndBuildMap(this, -21.0f);
for (MxS32 i = 0; i < m_animMaps.size(); i++) {
if (m_animMaps[i]->GetWorldSpeed() == -21.0f) {
@ -434,7 +434,7 @@ inline MxU32 LegoExtraActor::VTable0x6c(
LegoAnimPresenterSet& presenters = p_boundary->GetPresenters();
for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) {
if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) {
if ((*itap)->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3)) {
return 1;
}
}

View File

@ -471,7 +471,7 @@ MxU32 LegoPathActor::VTable0x6c(
LegoAnimPresenterSet& presenters = p_boundary->GetPresenters();
for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) {
if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) {
if ((*itap)->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3)) {
return 1;
}
}

View File

@ -341,15 +341,15 @@ MxU32 LegoPathBoundary::Intersect(
// FUNCTION: BETA10 0x100b2220
MxU32 LegoPathBoundary::AddPresenterIfInRange(LegoAnimPresenter* p_presenter)
{
Mx3DPointFloat unk0x30;
Mx3DPointFloat centerDistance;
unk0x30 = m_centerPoint;
unk0x30 -= p_presenter->m_unk0xa8;
centerDistance = m_centerPoint;
centerDistance -= p_presenter->m_centerPoint;
float len = unk0x30.LenSquared();
float local20 = p_presenter->m_unk0xa4 + m_boundingRadius;
float len = centerDistance.LenSquared();
float radiusSquared = p_presenter->m_boundingRadius + m_boundingRadius;
if (len > 0.001 && len > local20 * local20) {
if (len > 0.001 && len > radiusSquared * radiusSquared) {
return 0;
}

View File

@ -68,7 +68,7 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction,
case c_h: {
LegoHideAnimPresenter* presenter = m_world->GetHideAnimPresenter();
if (presenter != NULL) {
presenter->FUN_1006db40(p_data * 100);
presenter->ApplyVisibility(p_data * 100);
}
break;
}

View File

@ -117,7 +117,7 @@ void CarRace::ReadyWorld()
{
assert(m_hideAnim);
LegoWorld::ReadyWorld();
m_hideAnim->FUN_1006db40(0);
m_hideAnim->ApplyVisibility(0);
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);

View File

@ -81,7 +81,7 @@ void JetskiRace::ReadyWorld()
{
assert(m_hideAnim);
LegoWorld::ReadyWorld();
m_hideAnim->FUN_1006db40(0);
m_hideAnim->ApplyVisibility(0);
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);
@ -213,7 +213,7 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
result = 1;
}
else if (m_playerLastPathStruct == 0xf) {
m_hideAnim->FUN_1006db40(m_playerLaps * 200 + 100);
m_hideAnim->ApplyVisibility(m_playerLaps * 200 + 100);
result = 1;
}

View File

@ -432,7 +432,7 @@ inline MxU32 LegoCarRaceActor::VTable0x6c(
LegoAnimPresenterSet& presenters = p_boundary->GetPresenters();
for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) {
if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) {
if ((*itap)->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3)) {
return 1;
}
}
@ -516,7 +516,7 @@ inline MxU32 LegoJetskiRaceActor::VTable0x6c(
LegoAnimPresenterSet& presenters = p_boundary->GetPresenters();
for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) {
if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) {
if ((*itap)->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3)) {
return 1;
}
}

View File

@ -54,21 +54,21 @@ void LegoAnimPresenter::Init()
m_roiMapSize = 0;
m_managedActors = NULL;
m_sceneROIs = NULL;
m_unk0x78 = NULL;
m_transform = NULL;
m_flags = 0;
m_unk0xa8.Clear();
m_unk0xa4 = 0;
m_centerPoint.Clear();
m_boundingRadius = 0;
m_currentWorld = NULL;
m_unk0x95 = FALSE;
m_animationFinished = FALSE;
m_worldId = -1;
m_substMap = NULL;
m_worldAtom.Clear();
m_unk0x9c = 0;
m_unk0x8c = NULL;
m_unk0x90 = NULL;
m_unk0x94 = 0;
m_unk0x96 = TRUE;
m_unk0xa0 = NULL;
m_roiTransformApplied = 0;
m_ptAtCamROI = NULL;
m_ptAtCamNames = NULL;
m_ptAtCamCount = 0;
m_localActors = TRUE;
m_roiTransform = NULL;
}
// FUNCTION: LEGO1 0x10068770
@ -91,12 +91,12 @@ void LegoAnimPresenter::Destroy(MxBool p_fromDestructor)
}
if (m_managedActors != NULL) {
FUN_1006aa60();
ReleaseManagedActors();
delete m_managedActors;
}
if (m_unk0x78 != NULL) {
delete m_unk0x78;
if (m_transform != NULL) {
delete m_transform;
}
if (m_substMap != NULL) {
@ -112,22 +112,22 @@ void LegoAnimPresenter::Destroy(MxBool p_fromDestructor)
delete m_substMap;
}
if (m_unk0x90 != NULL) {
for (MxS32 i = 0; i < m_unk0x94; i++) {
if (m_unk0x90[i] != NULL) {
delete[] m_unk0x90[i];
if (m_ptAtCamNames != NULL) {
for (MxS32 i = 0; i < m_ptAtCamCount; i++) {
if (m_ptAtCamNames[i] != NULL) {
delete[] m_ptAtCamNames[i];
}
}
delete[] m_unk0x90;
delete[] m_ptAtCamNames;
}
if (m_unk0x8c != NULL) {
delete[] m_unk0x8c;
if (m_ptAtCamROI != NULL) {
delete[] m_ptAtCamROI;
}
if (m_unk0xa0 != NULL) {
delete m_unk0xa0;
if (m_roiTransform != NULL) {
delete m_roiTransform;
}
Init();
@ -150,16 +150,16 @@ MxResult LegoAnimPresenter::CreateAnim(MxStreamChunk* p_chunk)
if (storage.Read(&magicSig, sizeof(MxS32)) != SUCCESS || magicSig != 0x11) {
goto done;
}
if (storage.Read(&m_unk0xa4, sizeof(float)) != SUCCESS) {
if (storage.Read(&m_boundingRadius, sizeof(float)) != SUCCESS) {
goto done;
}
if (storage.Read(&m_unk0xa8[0], sizeof(float)) != SUCCESS) {
if (storage.Read(&m_centerPoint[0], sizeof(float)) != SUCCESS) {
goto done;
}
if (storage.Read(&m_unk0xa8[1], sizeof(float)) != SUCCESS) {
if (storage.Read(&m_centerPoint[1], sizeof(float)) != SUCCESS) {
goto done;
}
if (storage.Read(&m_unk0xa8[2], sizeof(float)) != SUCCESS) {
if (storage.Read(&m_centerPoint[2], sizeof(float)) != SUCCESS) {
goto done;
}
if (storage.Read(&parseScene, sizeof(LegoS32)) != SUCCESS) {
@ -190,24 +190,24 @@ MxResult LegoAnimPresenter::CreateAnim(MxStreamChunk* p_chunk)
}
// FUNCTION: LEGO1 0x10069150
LegoChar* LegoAnimPresenter::FUN_10069150(const LegoChar* p_und1)
LegoChar* LegoAnimPresenter::GetActorName(const LegoChar* p_name)
{
LegoChar* str;
if (LegoCharacterManager::IsActor(p_und1 + 1)) {
str = new LegoChar[strlen(p_und1)];
if (LegoCharacterManager::IsActor(p_name + 1)) {
str = new LegoChar[strlen(p_name)];
if (str != NULL) {
strcpy(str, p_und1 + 1);
strcpy(str, p_name + 1);
}
}
else {
LegoChar buffer[32];
sprintf(buffer, "%d", m_action->GetUnknown24());
str = new LegoChar[strlen(p_und1) + strlen(buffer) + strlen(GetActionObjectName()) + 1];
str = new LegoChar[strlen(p_name) + strlen(buffer) + strlen(GetActionObjectName()) + 1];
if (str != NULL) {
strcpy(str, p_und1);
strcpy(str, p_name);
strcat(str, buffer);
strcat(str, GetActionObjectName());
}
@ -217,7 +217,7 @@ LegoChar* LegoAnimPresenter::FUN_10069150(const LegoChar* p_und1)
}
// FUNCTION: LEGO1 0x100692b0
void LegoAnimPresenter::FUN_100692b0()
void LegoAnimPresenter::CreateManagedActors()
{
m_managedActors = new LegoROIList();
@ -229,7 +229,7 @@ void LegoAnimPresenter::FUN_100692b0()
LegoU32 actorType = m_anim->GetActorType(i);
LegoROI* roi = NULL;
if (actorType == LegoAnimActorEntry::e_actorType2) {
if (actorType == LegoAnimActorEntry::e_managedLegoActor) {
LegoChar* src;
if (str[0] == '*') {
src = str + 1;
@ -244,44 +244,44 @@ void LegoAnimPresenter::FUN_100692b0()
roi->SetVisibility(FALSE);
}
}
else if (actorType == LegoAnimActorEntry::e_actorType4) {
else if (actorType == LegoAnimActorEntry::e_managedInvisibleRoi) {
LegoChar* baseName = new LegoChar[strlen(str)];
strcpy(baseName, str + 1);
strlwr(baseName);
LegoChar* und = FUN_10069150(str);
roi = CharacterManager()->FUN_10085a80(und, baseName, TRUE);
LegoChar* roiName = GetActorName(str);
roi = CharacterManager()->FUN_10085a80(roiName, baseName, TRUE);
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
delete[] baseName;
delete[] und;
delete[] roiName;
}
else if (actorType == LegoAnimActorEntry::e_actorType3) {
else if (actorType == LegoAnimActorEntry::e_managedInvisibleRoiTrimmed) {
LegoChar* lodName = new LegoChar[strlen(str)];
strcpy(lodName, str + 1);
for (LegoChar* i = &lodName[strlen(lodName) - 1]; i > lodName; i--) {
if ((*i < '0' || *i > '9') && *i != '_') {
for (LegoChar* c = &lodName[strlen(lodName) - 1]; c > lodName; c--) {
if ((*c < '0' || *c > '9') && *c != '_') {
break;
}
*i = '\0';
*c = '\0';
}
strlwr(lodName);
LegoChar* und = FUN_10069150(str);
roi = CharacterManager()->CreateAutoROI(und, lodName, TRUE);
LegoChar* roiName = GetActorName(str);
roi = CharacterManager()->CreateAutoROI(roiName, lodName, TRUE);
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
delete[] lodName;
delete[] und;
delete[] roiName;
}
if (roi != NULL) {
@ -295,7 +295,7 @@ void LegoAnimPresenter::FUN_100692b0()
// FUNCTION: LEGO1 0x100695c0
// FUNCTION: BETA10 0x1004f359
void LegoAnimPresenter::FUN_100695c0()
void LegoAnimPresenter::CreateSceneROIs()
{
m_sceneROIs = new LegoROIList();
@ -304,10 +304,10 @@ void LegoAnimPresenter::FUN_100695c0()
LegoU32 numActors = m_anim->GetNumActors();
for (LegoU32 i = 0; i < numActors; i++) {
if (FUN_100698b0(rois, m_anim->GetActorName(i)) == FALSE) {
if (AppendROIToScene(rois, m_anim->GetActorName(i)) == FALSE) {
LegoU32 actorType = m_anim->GetActorType(i);
if (actorType == LegoAnimActorEntry::e_actorType5 || actorType == LegoAnimActorEntry::e_actorType6) {
if (actorType == LegoAnimActorEntry::e_sceneRoi1 || actorType == LegoAnimActorEntry::e_sceneRoi2) {
LegoChar lodName[256];
const LegoChar* actorName = m_anim->GetActorName(i);
@ -321,7 +321,7 @@ void LegoAnimPresenter::FUN_100695c0()
strlwr(lodName);
CharacterManager()->CreateAutoROI(actorName, lodName, FALSE);
FUN_100698b0(rois, actorName);
AppendROIToScene(rois, actorName);
}
}
}
@ -356,13 +356,13 @@ LegoChar* LegoAnimPresenter::GetVariableOrIdentity(const LegoChar* p_varName, co
}
// FUNCTION: LEGO1 0x100698b0
LegoBool LegoAnimPresenter::FUN_100698b0(const CompoundObject& p_rois, const LegoChar* p_und2)
LegoBool LegoAnimPresenter::AppendROIToScene(const CompoundObject& p_rois, const LegoChar* p_varName)
{
LegoBool result = FALSE;
LegoChar* str;
if (*(str = GetVariableOrIdentity(p_und2, NULL)) == '*') {
LegoChar* tmp = FUN_10069150(str);
if (*(str = GetVariableOrIdentity(p_varName, NULL)) == '*') {
LegoChar* tmp = GetActorName(str);
delete[] str;
str = tmp;
}
@ -407,12 +407,12 @@ LegoROI* LegoAnimPresenter::FindROI(const LegoChar* p_name)
}
// FUNCTION: LEGO1 0x10069b10
void LegoAnimPresenter::FUN_10069b10()
void LegoAnimPresenter::BuildROIMap()
{
LegoAnimStructMap anims;
if (m_unk0x8c != NULL) {
memset(m_unk0x8c, 0, m_unk0x94 * sizeof(*m_unk0x8c));
if (m_ptAtCamROI != NULL) {
memset(m_ptAtCamROI, 0, m_ptAtCamCount * sizeof(*m_ptAtCamROI));
}
UpdateStructMapAndROIIndex(anims, m_anim->GetRoot(), NULL);
@ -431,10 +431,10 @@ void LegoAnimPresenter::FUN_10069b10()
m_roiMap[index] = (*it).second.m_roi;
if (m_roiMap[index]->GetName() != NULL) {
for (MxS32 i = 0; i < m_unk0x94; i++) {
if (m_unk0x8c[i] == NULL && m_unk0x90[i] != NULL) {
if (!strcmpi(m_unk0x90[i], m_roiMap[index]->GetName())) {
m_unk0x8c[i] = m_roiMap[index];
for (MxS32 i = 0; i < m_ptAtCamCount; i++) {
if (m_ptAtCamROI[i] == NULL && m_ptAtCamNames[i] != NULL) {
if (!strcmpi(m_ptAtCamNames[i], m_roiMap[index]->GetName())) {
m_ptAtCamROI[i] = m_roiMap[index];
break;
}
}
@ -458,7 +458,7 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndex(LegoAnimStructMap& p_map, Leg
if (name != NULL && *name != '-') {
if (*name == '*') {
name = und2 = FUN_10069150(name);
name = und2 = GetActorName(name);
}
und = GetVariableOrIdentity(name, p_roi != NULL ? p_roi->GetName() : NULL);
@ -503,13 +503,13 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndex(LegoAnimStructMap& p_map, Leg
void LegoAnimPresenter::UpdateStructMapAndROIIndexForNode(
LegoAnimStructMap& p_map,
LegoAnimNodeData* p_data,
const LegoChar* p_und,
const LegoChar* p_key,
LegoROI* p_roi
)
{
LegoAnimStructMap::iterator it;
it = p_map.find(p_und);
it = p_map.find(p_key);
if (it == p_map.end()) {
LegoAnimStruct animStruct;
animStruct.m_index = p_map.size() + 1;
@ -517,10 +517,10 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndexForNode(
p_data->SetROIIndex(animStruct.m_index);
LegoChar* und = new LegoChar[strlen(p_und) + 1];
strcpy(und, p_und);
LegoChar* key = new LegoChar[strlen(p_key) + 1];
strcpy(key, p_key);
p_map[und] = animStruct;
p_map[key] = animStruct;
}
else {
p_data->SetROIIndex((*it).second.m_index);
@ -529,7 +529,7 @@ void LegoAnimPresenter::UpdateStructMapAndROIIndexForNode(
// FUNCTION: LEGO1 0x1006aa60
// FUNCTION: BETA10 0x1004feee
void LegoAnimPresenter::FUN_1006aa60()
void LegoAnimPresenter::ReleaseManagedActors()
{
LegoROIListCursor cursor(m_managedActors);
LegoROI* roi;
@ -537,16 +537,16 @@ void LegoAnimPresenter::FUN_1006aa60()
while (cursor.Next(roi)) {
const char* name = roi->GetName();
if (m_unk0x96 || !CharacterManager()->IsActor(name)) {
if (m_localActors || !CharacterManager()->IsActor(name)) {
CharacterManager()->ReleaseActor(name);
}
}
}
// FUNCTION: LEGO1 0x1006ab70
void LegoAnimPresenter::FUN_1006ab70()
void LegoAnimPresenter::AppendManagedActors()
{
if (m_unk0x96) {
if (m_localActors) {
AnimationManager()->FUN_10063270(m_managedActors, this);
}
else {
@ -555,25 +555,25 @@ void LegoAnimPresenter::FUN_1006ab70()
}
// FUNCTION: LEGO1 0x1006aba0
LegoBool LegoAnimPresenter::FUN_1006aba0()
LegoBool LegoAnimPresenter::VerifyAnimationTree()
{
return FUN_1006abb0(m_anim->GetRoot(), 0);
return VerifyAnimationNode(m_anim->GetRoot(), NULL);
}
// FUNCTION: LEGO1 0x1006abb0
MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi)
MxBool LegoAnimPresenter::VerifyAnimationNode(LegoTreeNode* p_node, LegoROI* p_roi)
{
MxBool result = FALSE;
LegoROI* roi = p_roi;
LegoChar* und = NULL;
LegoChar* varOrName = NULL;
const LegoChar* name = ((LegoAnimNodeData*) p_node->GetData())->GetName();
MxS32 i, count;
if (name != NULL && *name != '-') {
und = GetVariableOrIdentity(name, p_roi != NULL ? p_roi->GetName() : NULL);
varOrName = GetVariableOrIdentity(name, p_roi != NULL ? p_roi->GetName() : NULL);
if (p_roi == NULL) {
roi = FindROI(und);
roi = FindROI(varOrName);
if (roi == NULL) {
goto done;
@ -584,7 +584,7 @@ MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi)
if (child == NULL) {
if (FindROI(name) != NULL) {
if (FUN_1006abb0(p_node, NULL)) {
if (VerifyAnimationNode(p_node, NULL)) {
result = TRUE;
}
}
@ -596,7 +596,7 @@ MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi)
count = p_node->GetNumChildren();
for (i = 0; i < count; i++) {
if (!FUN_1006abb0(p_node->GetChild(i), roi)) {
if (!VerifyAnimationNode(p_node->GetChild(i), roi)) {
goto done;
}
}
@ -604,8 +604,8 @@ MxBool LegoAnimPresenter::FUN_1006abb0(LegoTreeNode* p_node, LegoROI* p_roi)
result = TRUE;
done:
if (und != NULL) {
delete[] und;
if (varOrName != NULL) {
delete[] varOrName;
}
return result;
@ -637,12 +637,12 @@ void LegoAnimPresenter::PutFrame()
time = 0;
}
FUN_1006b9a0(m_anim, time, m_unk0x78);
ApplyTransformWithVisibilityAndCam(m_anim, time, m_transform);
if (m_unk0x8c != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) {
for (MxS32 i = 0; i < m_unk0x94; i++) {
if (m_unk0x8c[i] != NULL) {
MxMatrix mat(m_unk0x8c[i]->GetLocal2World());
if (m_ptAtCamROI != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) {
for (MxS32 i = 0; i < m_ptAtCamCount; i++) {
if (m_ptAtCamROI[i] != NULL) {
MxMatrix mat(m_ptAtCamROI[i]->GetLocal2World());
Vector3 pos(mat[0]);
Vector3 dir(mat[1]);
@ -664,8 +664,8 @@ void LegoAnimPresenter::PutFrame()
dir *= dirsqr;
up *= upsqr;
m_unk0x8c[i]->SetLocal2World(mat);
m_unk0x8c[i]->WrappedUpdateWorldData();
m_ptAtCamROI[i]->SetLocal2World(mat);
m_ptAtCamROI[i]->WrappedUpdateWorldData();
}
}
}
@ -674,7 +674,7 @@ void LegoAnimPresenter::PutFrame()
// FUNCTION: LEGO1 0x1006afc0
// FUNCTION: BETA10 0x1005059a
MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und)
MxResult LegoAnimPresenter::GetTransforms(MxMatrix*& p_matrix, float p_time)
{
MxU32 length = m_roiMapSize + 1;
p_matrix = new MxMatrix[length];
@ -686,7 +686,7 @@ MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und)
}
}
FUN_1006b900(m_anim, p_und, m_unk0x78);
ApplyTransform(m_anim, p_time, m_transform);
for (i = 1; i < length; i++) {
MxMatrix mat;
@ -703,7 +703,7 @@ MxResult LegoAnimPresenter::FUN_1006afc0(MxMatrix*& p_matrix, float p_und)
// FUNCTION: LEGO1 0x1006b140
// FUNCTION: BETA10 0x100507e0
MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi)
MxResult LegoAnimPresenter::CopyTransform(LegoROI* p_roi)
{
if (p_roi == NULL) {
return FAILURE;
@ -717,16 +717,16 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi)
MxMatrix inverse;
const Matrix4& local2world = p_roi->GetLocal2World();
MxMatrix* local5c;
MxMatrix* roiTransforms;
MxU32 i;
if (FUN_1006afc0(local5c, 0.0f) != SUCCESS) {
if (GetTransforms(roiTransforms, 0.0f) != SUCCESS) {
goto done;
}
for (i = 1; i <= m_roiMapSize; i++) {
if (m_roiMap[i] == p_roi) {
if (local5c[i].Invert(inverse) != SUCCESS) {
if (roiTransforms[i].Invert(inverse) != SUCCESS) {
goto done;
}
@ -736,15 +736,15 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi)
{
mn->Product(inverse, local2world);
SetUnknown0xa0(mn);
delete[] local5c;
SetUnknown0x0cTo1();
SetRoiTransform(mn);
delete[] roiTransforms;
SetRoiTransformApplied();
MxMatrix local140(*m_unk0x78);
MxMatrix localf8;
MxMatrix originalTransform(*m_transform);
MxMatrix newTransform;
localf8.Product(local140, *m_unk0xa0);
*m_unk0x78 = localf8;
newTransform.Product(originalTransform, *m_roiTransform);
*m_transform = newTransform;
return SUCCESS;
}
@ -753,8 +753,8 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi)
delete mn;
}
if (local5c != NULL) {
delete[] local5c;
if (roiTransforms != NULL) {
delete[] roiTransforms;
}
return FAILURE;
@ -790,22 +790,22 @@ void LegoAnimPresenter::ReadyTickle()
void LegoAnimPresenter::StartingTickle()
{
SubstituteVariables();
FUN_100692b0();
FUN_100695c0();
CreateManagedActors();
CreateSceneROIs();
if (m_flags & c_mustSucceed && !FUN_1006aba0()) {
if (m_flags & c_mustSucceed && !VerifyAnimationTree()) {
goto done;
}
FUN_10069b10();
BuildROIMap();
SetDisabled(TRUE);
if (m_unk0x78 == NULL) {
if (m_transform == NULL) {
if (fabs(m_action->GetDirection()[0]) >= 0.00000047683716F ||
fabs(m_action->GetDirection()[1]) >= 0.00000047683716F ||
fabs(m_action->GetDirection()[2]) >= 0.00000047683716F) {
m_unk0x78 = new MxMatrix();
CalcLocalTransform(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), *m_unk0x78);
m_transform = new MxMatrix();
CalcLocalTransform(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), *m_transform);
}
else if (m_roiMap != NULL) {
LegoROI* roi = m_roiMap[1];
@ -813,7 +813,7 @@ void LegoAnimPresenter::StartingTickle()
if (roi != NULL) {
MxMatrix mat;
mat = roi->GetLocal2World();
m_unk0x78 = new MxMatrix(mat);
m_transform = new MxMatrix(mat);
}
}
}
@ -829,11 +829,11 @@ void LegoAnimPresenter::StartingTickle()
ProgressTickleState(e_streaming);
if (m_compositePresenter && m_compositePresenter->IsA("LegoAnimMMPresenter")) {
m_unk0x96 = ((LegoAnimMMPresenter*) m_compositePresenter)->FUN_1004b8b0();
m_localActors = ((LegoAnimMMPresenter*) m_compositePresenter)->FUN_1004b8b0();
m_compositePresenter->AdvanceSerialAction(this);
}
VTable0x8c();
AddToWorld();
done:
if (m_sceneROIs != NULL) {
@ -850,7 +850,7 @@ void LegoAnimPresenter::StreamingTickle()
m_subscriber->FreeDataChunk(chunk);
}
if (m_unk0x95) {
if (m_animationFinished) {
ProgressTickleState(e_done);
if (m_compositePresenter) {
if (m_compositePresenter->IsA("LegoAnimMMPresenter")) {
@ -860,7 +860,7 @@ void LegoAnimPresenter::StreamingTickle()
}
else {
if (m_action->GetElapsedTime() > m_anim->GetDuration() + m_action->GetStartTime()) {
m_unk0x95 = TRUE;
m_animationFinished = TRUE;
}
}
}
@ -891,7 +891,7 @@ const char* LegoAnimPresenter::GetActionObjectName()
// FUNCTION: LEGO1 0x1006b900
// FUNCTION: BETA10 0x100510d8
void LegoAnimPresenter::FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix)
void LegoAnimPresenter::ApplyTransform(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix)
{
LegoTreeNode* root = p_anim->GetRoot();
MxMatrix mat;
@ -916,7 +916,7 @@ void LegoAnimPresenter::FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p
// FUNCTION: LEGO1 0x1006b9a0
// FUNCTION: BETA10 0x1005118b
void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix)
void LegoAnimPresenter::ApplyTransformWithVisibilityAndCam(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix)
{
LegoTreeNode* root = p_anim->GetRoot();
MxMatrix mat;
@ -1007,43 +1007,43 @@ void LegoAnimPresenter::ParseExtra()
}
if (KeyValueStringParse(output, g_strPTATCAM, extraCopy)) {
list<char*> tmp;
list<char*> tokens;
if (m_unk0x90 != NULL) {
for (MxS32 i = 0; i < m_unk0x94; i++) {
if (m_unk0x90[i] != NULL) {
if (m_ptAtCamNames != NULL) {
for (MxS32 i = 0; i < m_ptAtCamCount; i++) {
if (m_ptAtCamNames[i] != NULL) {
// (modernization) critical bug: wrong free
delete[] m_unk0x90;
delete[] m_ptAtCamNames;
}
}
delete[] m_unk0x90;
m_unk0x90 = NULL;
delete[] m_ptAtCamNames;
m_ptAtCamNames = NULL;
}
if (m_unk0x8c != NULL) {
delete[] m_unk0x8c;
m_unk0x8c = NULL;
if (m_ptAtCamROI != NULL) {
delete[] m_ptAtCamROI;
m_ptAtCamROI = NULL;
}
char* token = strtok(output, g_parseExtraTokens);
while (token != NULL) {
char* valueCopy = new char[strlen(token) + 1];
strcpy(valueCopy, token);
tmp.push_back(valueCopy);
tokens.push_back(valueCopy);
token = strtok(NULL, g_parseExtraTokens);
}
m_unk0x94 = tmp.size();
if (m_unk0x94 != 0) {
m_unk0x8c = new LegoROI*[m_unk0x94];
m_unk0x90 = new char*[m_unk0x94];
memset(m_unk0x8c, 0, sizeof(*m_unk0x8c) * m_unk0x94);
memset(m_unk0x90, 0, sizeof(*m_unk0x90) * m_unk0x94);
m_ptAtCamCount = tokens.size();
if (m_ptAtCamCount != 0) {
m_ptAtCamROI = new LegoROI*[m_ptAtCamCount];
m_ptAtCamNames = new char*[m_ptAtCamCount];
memset(m_ptAtCamROI, 0, sizeof(*m_ptAtCamROI) * m_ptAtCamCount);
memset(m_ptAtCamNames, 0, sizeof(*m_ptAtCamNames) * m_ptAtCamCount);
MxS32 i = 0;
for (list<char*>::iterator it = tmp.begin(); it != tmp.end(); it++, i++) {
m_unk0x90[i] = *it;
for (list<char*>::iterator it = tokens.begin(); it != tokens.end(); it++, i++) {
m_ptAtCamNames[i] = *it;
}
}
}
@ -1052,13 +1052,13 @@ void LegoAnimPresenter::ParseExtra()
// FUNCTION: LEGO1 0x1006c570
// FUNCTION: BETA10 0x10051ab3
void LegoAnimPresenter::VTable0xa0(Matrix4& p_matrix)
void LegoAnimPresenter::SetTransform(Matrix4& p_matrix)
{
if (m_unk0x78 != NULL) {
delete m_unk0x78;
if (m_transform != NULL) {
delete m_transform;
}
m_unk0x78 = new MxMatrix(p_matrix);
m_transform = new MxMatrix(p_matrix);
}
// FUNCTION: LEGO1 0x1006c620
@ -1087,7 +1087,7 @@ void LegoAnimPresenter::EndAction()
}
if (m_anim != NULL) {
FUN_1006b9a0(m_anim, m_anim->GetDuration(), m_unk0x78);
ApplyTransformWithVisibilityAndCam(m_anim, m_anim->GetDuration(), m_transform);
}
if (m_roiMapSize != 0 && m_roiMap != NULL && m_roiMap[1] != NULL && m_flags & c_hideOnStop) {
@ -1099,8 +1099,8 @@ void LegoAnimPresenter::EndAction()
}
SetDisabled(FALSE);
FUN_1006ab70();
VTable0x90();
AppendManagedActors();
RemoveFromWorld();
if (m_currentWorld != NULL) {
m_currentWorld->Remove(this);
@ -1111,24 +1111,24 @@ void LegoAnimPresenter::EndAction()
// FUNCTION: LEGO1 0x1006c7a0
// FUNCTION: BETA10 0x10051da6
void LegoAnimPresenter::FUN_1006c7a0()
void LegoAnimPresenter::ApplyFinishedTransform()
{
if (m_anim != NULL) {
FUN_1006b9a0(m_anim, m_anim->GetDuration(), m_unk0x78);
ApplyTransformWithVisibilityAndCam(m_anim, m_anim->GetDuration(), m_transform);
}
m_unk0x95 = TRUE;
m_animationFinished = TRUE;
}
// FUNCTION: LEGO1 0x1006c7d0
// FUNCTION: BETA10 0x10051e07
void LegoAnimPresenter::VTable0x8c()
void LegoAnimPresenter::AddToWorld()
{
if (m_unk0x78) {
m_unk0xa8 += (*m_unk0x78)[3];
if (m_transform) {
m_centerPoint += (*m_transform)[3];
}
else {
m_unk0xa8 += m_action->GetLocation();
m_centerPoint += m_action->GetLocation();
}
if (m_currentWorld == NULL) {
@ -1145,7 +1145,7 @@ void LegoAnimPresenter::VTable0x8c()
// FUNCTION: LEGO1 0x1006c860
// FUNCTION: BETA10 0x10051f45
void LegoAnimPresenter::VTable0x90()
void LegoAnimPresenter::RemoveFromWorld()
{
if (m_currentWorld != NULL) {
m_currentWorld->RemovePresenterFromBoundaries(this);
@ -1179,26 +1179,34 @@ void LegoAnimPresenter::SetDisabled(MxBool p_disabled)
// FUNCTION: LEGO1 0x1006c8f0
// FUNCTION: BETA10 0x1005206c
MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3)
MxU32 LegoAnimPresenter::Intersect(
Vector3& p_rayOrigin,
Vector3& p_rayDirection,
float p_rayLength,
float p_radius,
Vector3& p_intersectionPoint
)
{
Mx3DPointFloat a, b;
Mx3DPointFloat centerToRay, rayEnd;
b = p_v2;
b *= p_f1;
b += p_v1;
rayEnd = p_rayDirection;
rayEnd *= p_rayLength;
rayEnd += p_rayOrigin;
a = b;
a -= m_unk0xa8;
centerToRay = rayEnd;
centerToRay -= m_centerPoint;
float len = a.LenSquared();
float len = centerToRay.LenSquared();
if (len <= 0.0f) {
return TRUE;
}
len = sqrt(len);
if (len <= m_unk0xa4 + p_f2 && m_roiMapSize != 0 && m_roiMap != NULL) {
if (len <= m_boundingRadius + p_radius && m_roiMapSize != 0 && m_roiMap != NULL) {
for (MxU32 i = 1; i <= m_roiMapSize; i++) {
if (m_roiMap[i]->GetLODCount() != 0 && m_roiMap[i]->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, FALSE)) {
if (m_roiMap[i]->GetLODCount() != 0 &&
m_roiMap[i]
->Intersect(p_rayOrigin, p_rayDirection, p_rayLength, p_radius, p_intersectionPoint, FALSE)) {
return TRUE;
}
}
@ -1209,7 +1217,7 @@ MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, fl
// FUNCTION: LEGO1 0x1006ca50
// FUNCTION: BETA10 0x100521d0
MxResult LegoAnimPresenter::VTable0x98(LegoPathBoundary* p_boundary)
MxResult LegoAnimPresenter::AddActors(LegoPathBoundary* p_boundary)
{
for (MxU32 i = 1; i <= m_roiMapSize; i++) {
LegoEntity* entity = m_roiMap[i]->GetEntity();
@ -1231,7 +1239,7 @@ void LegoLoopingAnimPresenter::StreamingTickle()
m_subscriber->FreeDataChunk(chunk);
}
if (m_unk0x95) {
if (m_animationFinished) {
ProgressTickleState(e_done);
if (m_compositePresenter) {
if (m_compositePresenter->IsA("LegoAnimMMPresenter")) {
@ -1242,7 +1250,7 @@ void LegoLoopingAnimPresenter::StreamingTickle()
else {
if (m_action->GetDuration() != -1) {
if (m_action->GetElapsedTime() > m_action->GetDuration() + m_action->GetStartTime()) {
m_unk0x95 = TRUE;
m_animationFinished = TRUE;
}
}
}
@ -1261,12 +1269,12 @@ void LegoLoopingAnimPresenter::PutFrame()
time = 0;
}
FUN_1006b9a0(m_anim, time, m_unk0x78);
ApplyTransformWithVisibilityAndCam(m_anim, time, m_transform);
if (m_unk0x8c != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) {
for (MxS32 i = 0; i < m_unk0x94; i++) {
if (m_unk0x8c[i] != NULL) {
MxMatrix mat(m_unk0x8c[i]->GetLocal2World());
if (m_ptAtCamROI != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) {
for (MxS32 i = 0; i < m_ptAtCamCount; i++) {
if (m_ptAtCamROI[i] != NULL) {
MxMatrix mat(m_ptAtCamROI[i]->GetLocal2World());
Vector3 pos(mat[0]);
Vector3 dir(mat[1]);
@ -1288,8 +1296,8 @@ void LegoLoopingAnimPresenter::PutFrame()
dir *= dirsqr;
up *= upsqr;
m_unk0x8c[i]->SetLocal2World(mat);
m_unk0x8c[i]->WrappedUpdateWorldData();
m_ptAtCamROI[i]->SetLocal2World(mat);
m_ptAtCamROI[i]->WrappedUpdateWorldData();
}
}
}
@ -1315,7 +1323,7 @@ void LegoLocomotionAnimPresenter::Init()
m_unk0xcc = -1;
m_unk0xd0 = -1;
m_roiMapList = NULL;
m_unk0xd4 = 0;
m_worldRefCounter = 0;
}
// FUNCTION: LEGO1 0x1006d0e0
@ -1384,7 +1392,7 @@ void LegoLocomotionAnimPresenter::ReadyTickle()
SendToCompositePresenter(Lego());
}
m_unk0xd4++;
m_worldRefCounter++;
}
}
@ -1405,7 +1413,7 @@ void LegoLocomotionAnimPresenter::StartingTickle()
// FUNCTION: LEGO1 0x1006d660
void LegoLocomotionAnimPresenter::StreamingTickle()
{
if (m_unk0xd4 == 0) {
if (m_worldRefCounter == 0) {
EndAction();
}
}
@ -1420,7 +1428,7 @@ void LegoLocomotionAnimPresenter::EndAction()
// FUNCTION: LEGO1 0x1006d680
// FUNCTION: BETA10 0x10052b3d
void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value)
void LegoLocomotionAnimPresenter::CreateROIAndBuildMap(LegoAnimActor* p_actor, MxFloat p_worldSpeed)
{
// This asserts that LegoLocomotionAnimPresenter is contained in legoanimpresenter.cpp
AUTOLOCK(m_criticalSection);
@ -1430,12 +1438,12 @@ void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p
const char* key = ((LegoAnimNodeData*) m_anim->GetRoot()->GetData())->GetName();
variableTable->SetVariable(key, p_actor->GetROI()->GetName());
FUN_100695c0();
FUN_10069b10();
CreateSceneROIs();
BuildROIMap();
if (m_roiMap != NULL) {
m_roiMapList->Append(m_roiMap);
p_actor->CreateAnimActorStruct(m_anim, p_value, m_roiMap, m_roiMapSize);
p_actor->CreateAnimActorStruct(m_anim, p_worldSpeed, m_roiMap, m_roiMapSize);
m_roiMap = NULL;
}
@ -1526,21 +1534,21 @@ void LegoHideAnimPresenter::StartingTickle()
LegoLoopingAnimPresenter::StartingTickle();
if (m_currentTickleState == e_streaming) {
FUN_1006dc10();
FUN_1006db40(0);
AssignIndiciesWithMap();
ApplyVisibility(0);
}
}
// FUNCTION: LEGO1 0x1006db40
// FUNCTION: BETA10 0x100531ab
void LegoHideAnimPresenter::FUN_1006db40(LegoTime p_time)
void LegoHideAnimPresenter::ApplyVisibility(LegoTime p_time)
{
FUN_1006db60(m_anim->GetRoot(), p_time);
ApplyVisibility(m_anim->GetRoot(), p_time);
}
// FUNCTION: LEGO1 0x1006db60
// FUNCTION: BETA10 0x100531de
void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time)
void LegoHideAnimPresenter::ApplyVisibility(LegoTreeNode* p_node, LegoTime p_time)
{
LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData();
MxBool newB = FALSE;
@ -1561,23 +1569,23 @@ void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time)
if (boundary != NULL) {
newB = data->GetVisibility(p_time);
previousB = boundary->GetFlag0x10();
boundary->SetFlag0x10(newB);
previousB = boundary->GetVisibility();
boundary->SetVisibility(newB);
}
}
for (MxS32 i = 0; i < p_node->GetNumChildren(); i++) {
FUN_1006db60(p_node->GetChild(i), p_time);
ApplyVisibility(p_node->GetChild(i), p_time);
}
}
// FUNCTION: LEGO1 0x1006dc10
// FUNCTION: BETA10 0x100532fd
void LegoHideAnimPresenter::FUN_1006dc10()
void LegoHideAnimPresenter::AssignIndiciesWithMap()
{
LegoHideAnimStructMap anims;
FUN_1006e3f0(anims, m_anim->GetRoot());
BuildMap(anims, m_anim->GetRoot());
if (m_boundaryMap != NULL) {
delete[] m_boundaryMap;
@ -1594,7 +1602,7 @@ void LegoHideAnimPresenter::FUN_1006dc10()
// FUNCTION: LEGO1 0x1006e3f0
// FUNCTION: BETA10 0x1005345e
void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node)
void LegoHideAnimPresenter::BuildMap(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node)
{
LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData();
const char* name = data->GetName();
@ -1603,7 +1611,7 @@ void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeN
LegoPathBoundary* boundary = m_currentWorld->FindPathBoundary(name);
if (boundary != NULL) {
FUN_1006e470(p_map, data, name, boundary);
CheckedAdd(p_map, data, name, boundary);
}
else {
data->SetBoundaryIndex(0);
@ -1612,13 +1620,13 @@ void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeN
MxS32 count = p_node->GetNumChildren();
for (MxS32 i = 0; i < count; i++) {
FUN_1006e3f0(p_map, p_node->GetChild(i));
BuildMap(p_map, p_node->GetChild(i));
}
}
// FUNCTION: LEGO1 0x1006e470
// FUNCTION: BETA10 0x10053520
void LegoHideAnimPresenter::FUN_1006e470(
void LegoHideAnimPresenter::CheckedAdd(
LegoHideAnimStructMap& p_map,
LegoAnimNodeData* p_data,
const char* p_name,

View File

@ -1208,19 +1208,19 @@ MxResult LegoAct2::InitializeShooting()
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim0");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, 0.0f);
ap->CreateROIAndBuildMap(m_unk0x1138, 0.0f);
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim2");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, 6.0f);
ap->CreateROIAndBuildMap(m_unk0x1138, 6.0f);
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim3");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, 3.0f);
ap->CreateROIAndBuildMap(m_unk0x1138, 3.0f);
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "BrShoot");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, -1.0f);
ap->CreateROIAndBuildMap(m_unk0x1138, -1.0f);
actor->SetWorldSpeed(0.0f);
m_unk0x1138->InitializeNextShot();

View File

@ -290,11 +290,11 @@ class LegoAnimNodeData : public LegoTreeNodeData {
// SIZE 0x08
struct LegoAnimActorEntry {
enum {
e_actorType2 = 2,
e_actorType3 = 3,
e_actorType4 = 4,
e_actorType5 = 5,
e_actorType6 = 6,
e_managedLegoActor = 2,
e_managedInvisibleRoiTrimmed = 3,
e_managedInvisibleRoi = 4,
e_sceneRoi1 = 5,
e_sceneRoi2 = 6,
};
LegoChar* m_name; // 0x00

View File

@ -37,7 +37,7 @@ class LegoWEGEdge : public LegoWEEdge {
c_bit1 = 0x01,
c_bit2 = 0x02,
c_bit3 = 0x04,
c_bit5 = 0x10
c_visible = 0x10
};
LegoWEGEdge();
@ -46,9 +46,9 @@ class LegoWEGEdge : public LegoWEEdge {
LegoS32 LinkEdgesAndFaces() override; // vtable+0x04
// FUNCTION: BETA10 0x100270c0
LegoU32 GetFlag0x10()
LegoU32 GetVisibility()
{
if (m_flags & c_bit5) {
if (m_flags & c_visible) {
return FALSE;
}
else {
@ -67,13 +67,13 @@ class LegoWEGEdge : public LegoWEEdge {
const LegoChar* GetName() { return m_name; }
// FUNCTION: BETA10 0x1005d5f0
void SetFlag0x10(LegoU32 p_disable)
void SetVisibility(LegoU32 p_disable)
{
if (p_disable) {
m_flags &= ~c_bit5;
m_flags &= ~c_visible;
}
else {
m_flags |= c_bit5;
m_flags |= c_visible;
}
}