|
10 | 10 | *****************************************************************************/ |
11 | 11 |
|
12 | 12 | #include "StdInc.h" |
| 13 | +#include "gamesa_renderware.h" |
| 14 | +#include "BoneNode_cSA.h" |
13 | 15 |
|
14 | 16 | extern CGameSA* pGame; |
15 | 17 |
|
@@ -65,6 +67,12 @@ CEntitySA::CEntitySA() |
65 | 67 | m_ulArrayID = INVALID_POOL_ARRAY_ID; |
66 | 68 | } |
67 | 69 |
|
| 70 | +void CEntitySA::UpdateRpHAnim() |
| 71 | +{ |
| 72 | + auto CEntity_UpdateRpHAnim = (void(__thiscall*)(CEntitySAInterface*))0x532B20; |
| 73 | + CEntity_UpdateRpHAnim(m_pInterface); |
| 74 | +} |
| 75 | + |
68 | 76 | /*VOID CEntitySA::SetModelAlpha ( int iAlpha ) |
69 | 77 | { |
70 | 78 | this->internalInterface->ModelClump->SetAlpha(iAlpha); |
@@ -583,6 +591,104 @@ bool CEntitySA::IsPlayingAnimation(char* szAnimName) |
583 | 591 | else return false; |
584 | 592 | } |
585 | 593 |
|
| 594 | +RwMatrixTag* CEntitySA::GetBoneRwMatrix(eBone boneId) |
| 595 | +{ |
| 596 | + RpClump* clump = GetRpClump(); |
| 597 | + if (!clump) |
| 598 | + return nullptr; |
| 599 | + RpHAnimHierarchy* hAnimHier = GetAnimHierarchyFromSkinClump(clump); |
| 600 | + if (hAnimHier) |
| 601 | + { |
| 602 | + int boneAnimIdIndex = RpHAnimIDGetIndex(hAnimHier, boneId); |
| 603 | + if (boneAnimIdIndex != -1) |
| 604 | + return &RpHAnimHierarchyGetMatrixArray(hAnimHier)[boneAnimIdIndex]; |
| 605 | + } |
| 606 | + return nullptr; |
| 607 | +} |
| 608 | + |
| 609 | +bool CEntitySA::SetBoneMatrix(eBone boneId, const CMatrix& matrix) |
| 610 | +{ |
| 611 | + RwMatrixTag* rwBoneMatrix = GetBoneRwMatrix(boneId); |
| 612 | + if (rwBoneMatrix) |
| 613 | + { |
| 614 | + CMatrixSAInterface boneMatrix(rwBoneMatrix, false); |
| 615 | + boneMatrix.SetMatrix(matrix.vRight, matrix.vFront, matrix.vUp, matrix.vPos); |
| 616 | + boneMatrix.UpdateRW(); |
| 617 | + return true; |
| 618 | + } |
| 619 | + return false; |
| 620 | +} |
| 621 | + |
| 622 | +bool CEntitySA::GetBoneRotation(eBone boneId, float& yaw, float& pitch, float& roll) |
| 623 | +{ |
| 624 | + RpClump* clump = GetRpClump(); |
| 625 | + if (clump) |
| 626 | + { |
| 627 | + // updating the bone frame orientation will also update its children |
| 628 | + // This rotation is only applied when UpdateElementRpHAnim is called |
| 629 | + CAnimBlendClumpDataSAInterface* clumpDataInterface = *pGame->GetClumpData(clump); |
| 630 | + AnimBlendFrameData* frameData = clumpDataInterface->GetFrameDataByNodeId(boneId); |
| 631 | + if (frameData) |
| 632 | + { |
| 633 | + RtQuat* boneOrientation = &frameData->m_pIFrame->orientation; |
| 634 | + RwV3d angles = {yaw, roll, pitch}; |
| 635 | + BoneNode_cSAInterface::QuatToEuler(boneOrientation, &angles); |
| 636 | + yaw = angles.x; |
| 637 | + roll = angles.y; |
| 638 | + pitch = angles.z; |
| 639 | + return true; |
| 640 | + } |
| 641 | + } |
| 642 | + return false; |
| 643 | + |
| 644 | +} |
| 645 | + |
| 646 | +bool CEntitySA::SetBoneRotation(eBone boneId, float yaw, float pitch, float roll) |
| 647 | +{ |
| 648 | + RpClump* clump = GetRpClump(); |
| 649 | + if (clump) |
| 650 | + { |
| 651 | + // updating the bone frame orientation will also update its children |
| 652 | + // This rotation is only applied when UpdateElementRpHAnim is called |
| 653 | + CAnimBlendClumpDataSAInterface* clumpDataInterface = *pGame->GetClumpData(clump); |
| 654 | + AnimBlendFrameData* frameData = clumpDataInterface->GetFrameDataByNodeId(boneId); |
| 655 | + if (frameData) |
| 656 | + { |
| 657 | + RtQuat* boneOrientation = &frameData->m_pIFrame->orientation; |
| 658 | + RwV3d angles = {yaw, roll, pitch}; |
| 659 | + BoneNode_cSAInterface::EulerToQuat(&angles, boneOrientation); |
| 660 | + return true; |
| 661 | + } |
| 662 | + } |
| 663 | + return false; |
| 664 | +} |
| 665 | + |
| 666 | +bool CEntitySA::GetBonePosition(eBone boneId, CVector& position) |
| 667 | +{ |
| 668 | + RwMatrixTag* rwBoneMatrix = GetBoneRwMatrix(boneId); |
| 669 | + if (rwBoneMatrix) |
| 670 | + { |
| 671 | + const RwV3d& pos = rwBoneMatrix->pos; |
| 672 | + position = {pos.x, pos.y, pos.z}; |
| 673 | + return true; |
| 674 | + } |
| 675 | + return false; |
| 676 | +} |
| 677 | + |
| 678 | +// NOTE: The position will be reset if UpdateElementRpHAnim is called after this. |
| 679 | +bool CEntitySA::SetBonePosition(eBone boneId, const CVector& position) |
| 680 | +{ |
| 681 | + RwMatrixTag* rwBoneMatrix = GetBoneRwMatrix(boneId); |
| 682 | + if (rwBoneMatrix) |
| 683 | + { |
| 684 | + CMatrixSAInterface boneMatrix(rwBoneMatrix, false); |
| 685 | + boneMatrix.SetTranslateOnly(position); |
| 686 | + boneMatrix.UpdateRW(); |
| 687 | + return true; |
| 688 | + } |
| 689 | + return false; |
| 690 | +} |
| 691 | + |
586 | 692 | BYTE CEntitySA::GetAreaCode() |
587 | 693 | { |
588 | 694 | return m_pInterface->m_areaCode; |
|
0 commit comments