| 700 | } |
| 701 | |
| 702 | void AlignEntityToSurface(ItemInfo* item, const Vector2& ellipse, float alpha, short constraintAngle) |
| 703 | { |
| 704 | // Reduce ellipse axis lengths for stability. |
| 705 | auto reducedEllipse = ellipse * 0.75f; |
| 706 | |
| 707 | // Probe heights at points around entity. |
| 708 | int frontHeight = GetPointCollision(*item, item->Pose.Orientation.y, reducedEllipse.y).GetFloorHeight(); |
| 709 | int backHeight = GetPointCollision(*item, item->Pose.Orientation.y + ANGLE(180.0f), reducedEllipse.y).GetFloorHeight(); |
| 710 | int leftHeight = GetPointCollision(*item, item->Pose.Orientation.y - ANGLE(90.0f), reducedEllipse.x).GetFloorHeight(); |
| 711 | int rightHeight = GetPointCollision(*item, item->Pose.Orientation.y + ANGLE(90.0f), reducedEllipse.x).GetFloorHeight(); |
| 712 | |
| 713 | // Calculate height deltas. |
| 714 | int forwardHeightDelta = backHeight - frontHeight; |
| 715 | int lateralHeightDelta = rightHeight - leftHeight; |
| 716 | |
| 717 | // Calculate extra rotation required. |
| 718 | auto extraRot = EulerAngles( |
| 719 | FROM_RAD(atan2(forwardHeightDelta, ellipse.y * 2)), |
| 720 | 0, |
| 721 | FROM_RAD(atan2(lateralHeightDelta, ellipse.x * 2))) - |
| 722 | EulerAngles(item->Pose.Orientation.x, 0, item->Pose.Orientation.z); |
| 723 | |
| 724 | // Rotate X axis. |
| 725 | if (abs(forwardHeightDelta) <= STEPUP_HEIGHT) |
| 726 | { |
| 727 | if (abs(extraRot.x) <= constraintAngle) |
| 728 | item->Pose.Orientation.x += extraRot.x * alpha; |
| 729 | } |
| 730 | |
| 731 | // Rotate Z axis. |
| 732 | if (abs(lateralHeightDelta) <= STEPUP_HEIGHT) |
| 733 | { |
| 734 | if (abs(extraRot.z) <= constraintAngle) |
| 735 | item->Pose.Orientation.z += extraRot.z * alpha; |
| 736 | } |
| 737 | } |
| 738 | |
| 739 | int GetQuadrant(short angle) |
| 740 | { |
no test coverage detected