diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index 2272b0f7..1ae41b21 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -14,7 +14,9 @@ class MxAtomId; class LegoEntity; class LegoAnimPresenter; class LegoNamedTexture; +class LegoTreeNode; +MxS16 CountTotalTreeNodes(LegoTreeNode* p_node); void FUN_1003e050(LegoAnimPresenter* p_presenter); Extra::ActionType MatchActionString(const char*); void InvokeAction(Extra::ActionType p_actionId, MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender); diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 82d3f3d2..3717ef71 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -6,6 +6,7 @@ #include "legoinputmanager.h" #include "legonamedtexture.h" #include "legoomni.h" +#include "legosoundmanager.h" #include "legoworld.h" #include "legoworldlist.h" #include "misc.h" @@ -20,10 +21,100 @@ #include #include -// STUB: LEGO1 0x1003e050 +// FUNCTION: LEGO1 0x1003df90 +MxS16 CountTotalTreeNodes(LegoTreeNode* p_node) +{ + MxS16 result = 1; + + for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) { + result += CountTotalTreeNodes(p_node->GetChild(i)); + } + + return result; +} + +// FUNCTION: LEGO1 0x1003dfd0 +LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index) +{ + LegoTreeNode* result = NULL; + + if (p_index == 0) { + result = p_node; + } + else { + for (LegoU32 i = 0; i < p_node->GetNumChildren(); i++) { + MxS16 count = CountTotalTreeNodes(p_node->GetChild(i)); + if (p_index > count) { + p_index -= count; + } + else { + result = GetTreeNode(p_node->GetChild(i), p_index - 1); + break; + } + } + } + + return result; +} + +// FUNCTION: LEGO1 0x1003e050 void FUN_1003e050(LegoAnimPresenter* p_presenter) { - // TODO + MxMatrix viewMatrix; + LegoTreeNode* rootNode = p_presenter->GetAnimation()->GetRoot(); + MxS16 nodesCount = CountTotalTreeNodes(rootNode); + + MxFloat cam; + LegoAnimNodeData* camData = NULL; + LegoAnimNodeData* targetData = NULL; + for (MxS16 i = 0; i < nodesCount; i++) { + if (targetData && camData) { + break; + } + + LegoTreeNode* node = GetTreeNode(rootNode, i); + LegoAnimNodeData* data = (LegoAnimNodeData*) node->GetData(); + + if (!strnicmp(data->GetName(), "CAM", strlen("CAM"))) { + camData = data; + cam = atof(strlen((data->GetName())) + 1 + data->GetName() - 3); + } + else if (!strcmpi(data->GetName(), "TARGET")) { + targetData = data; + } + } + + MxMatrix matrixCam; + MxMatrix matrixTarget; + matrixCam.SetIdentity(); + matrixTarget.SetIdentity(); + + camData->CreateLocalTransform((LegoFloat) 0, matrixCam); + targetData->CreateLocalTransform((LegoFloat) 0, matrixTarget); + + Mx3DPointFloat dir; + dir[0] = matrixTarget[3][0] - matrixCam[3][0]; + dir[1] = matrixTarget[3][1] - matrixCam[3][1]; + dir[2] = matrixTarget[3][2] - matrixCam[3][2]; + + MxFloat lensSquared = dir.LenSquared(); + if (lensSquared > 0.0f) { + float x = sqrt(lensSquared); + if (x > 0.0f) { + dir.DivScalarImpl(&x); + } + } + + Vector3 position(matrixCam[3]); + Vector3 up(matrixCam[1]); + CalcLocalTransform(position, dir, up, viewMatrix); + + LegoVideoManager* video = VideoManager(); + LegoROI* view = video->GetViewROI(); + view->WrappedSetLocalTransform(viewMatrix); + video->Get3DManager()->GetLego3DView()->Moved(*view); + FUN_1003eda0(); + video->Get3DManager()->SetFrustrum(cam, 0.1, 250.0); } // FUNCTION: LEGO1 0x1003e300 @@ -243,10 +334,22 @@ void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bO } } -// STUB: LEGO1 0x1003eda0 +// FUNCTION: LEGO1 0x1003eda0 void FUN_1003eda0() { - // TODO + Mx3DPointFloat vec; + vec.Clear(); + + LegoROI* viewROI = VideoManager()->GetViewROI(); + if (viewROI) { + viewROI->FUN_100a5a30(vec); + SoundManager()->FUN_1002a410( + viewROI->GetWorldPosition(), + viewROI->GetWorldDirection(), + viewROI->GetWorldUp(), + viewROI->GetWorldVelocity() + ); + } } // FUNCTION: LEGO1 0x1003ee00 diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 3527747c..d409d91d 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -210,6 +210,8 @@ class LegoAnimScene { LegoResult Read(LegoStorage* p_storage); undefined4 FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix); + inline LegoTranslationKey* GetUnknown0x04() { return m_unk0x04; } + private: LegoU16 m_unk0x00; // 0x00 LegoTranslationKey* m_unk0x04; // 0x04