MCPcopy Create free account
hub / github.com/TombEngine/TombEngine / TestItemAtNextCornerPosition

Function TestItemAtNextCornerPosition

TombEngine/Game/Lara/lara_tests.cpp:688–753  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

686}
687
688CornerTestResult TestItemAtNextCornerPosition(ItemInfo* item, CollisionInfo* coll, float angle, bool outer)
689{
690 auto* lara = GetLaraInfo(item);
691
692 auto result = CornerTestResult();
693
694 // Determine real turning angle
695 auto turnAngle = outer ? angle : -angle;
696
697 // Backup previous position into array
698 Pose pos[3] = { item->Pose, item->Pose, item->Pose };
699
700 // Do a two-step rotation check. First step is real resulting position, and second step is probing
701 // position. We need this because checking at exact ending position does not always return
702 // correct results with nearest ledge angle.
703
704 for (int i = 0; i < 2; i++)
705 {
706 // Determine collision box anchor point and rotate collision box around this anchor point.
707 // Then determine new test position from centerpoint of new collision box position.
708
709 // Push back item a bit to compensate for possible edge ledge cases
710 pos[i].Position.x -= round((coll->Setup.Radius * (outer ? -0.2f : 0.2f)) * phd_sin(pos[i].Orientation.y));
711 pos[i].Position.z -= round((coll->Setup.Radius * (outer ? -0.2f : 0.2f)) * phd_cos(pos[i].Orientation.y));
712
713 // Move item at the distance of full collision diameter plus half-radius margin to movement direction
714 pos[i].Position.x += round((coll->Setup.Radius * (i == 0 ? 2.0f : 2.5f)) * phd_sin(lara->Control.MoveAngle));
715 pos[i].Position.z += round((coll->Setup.Radius * (i == 0 ? 2.0f : 2.5f)) * phd_cos(lara->Control.MoveAngle));
716
717 // Determine anchor point
718 auto cX = pos[i].Position.x + round(coll->Setup.Radius * phd_sin(pos[i].Orientation.y));
719 auto cZ = pos[i].Position.z + round(coll->Setup.Radius * phd_cos(pos[i].Orientation.y));
720 cX += (coll->Setup.Radius * phd_sin(pos[i].Orientation.y + ANGLE(90.0f * -std::copysign(1.0f, angle))));
721 cZ += (coll->Setup.Radius * phd_cos(pos[i].Orientation.y + ANGLE(90.0f * -std::copysign(1.0f, angle))));
722
723 // Determine distance from anchor point to new item position
724 auto dist = Vector2(pos[i].Position.x, pos[i].Position.z) - Vector2(cX, cZ);
725 auto s = phd_sin(ANGLE(turnAngle));
726 auto c = phd_cos(ANGLE(turnAngle));
727
728 // Shift item to a new anchor point
729 pos[i].Position.x = dist.x * c - dist.y * s + cX;
730 pos[i].Position.z = dist.x * s + dist.y * c + cZ;
731
732 // Virtually rotate item to new angle
733 short newAngle = pos[i].Orientation.y - ANGLE(turnAngle);
734 pos[i].Orientation.y = newAngle;
735
736 // Snap to nearest ledge, if any.
737 item->Pose = pos[i];
738 SnapItemToLedge(item, coll, item->Pose.Orientation.y);
739
740 // Copy resulting position to an array and restore original item position.
741 pos[i] = item->Pose;
742 item->Pose = pos[2];
743
744 if (i == 1) // Both passes finished, construct the result.
745 {

Callers 1

TestLaraHangCornerFunction · 0.85

Calls 6

CornerTestResultClass · 0.85
phd_sinFunction · 0.85
phd_cosFunction · 0.85
ANGLEFunction · 0.85
SnapItemToLedgeFunction · 0.85
Vector2Function · 0.50

Tested by

no test coverage detected