| 38 | } |
| 39 | |
| 40 | void HairUnit::Update(const ItemInfo& item, int hairUnitID) |
| 41 | { |
| 42 | for (auto& segment : Segments) |
| 43 | segment.StoreInterpolationData(); |
| 44 | |
| 45 | const auto& player = GetLaraInfo(item); |
| 46 | |
| 47 | bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); |
| 48 | |
| 49 | // Get world matrix from head bone. |
| 50 | auto worldMatrix = Matrix::Identity; |
| 51 | g_Renderer.GetBoneMatrix(item.Index, GetRootMeshID(hairUnitID), &worldMatrix); |
| 52 | |
| 53 | // Apply base offset to world matrix. |
| 54 | auto relOffset = GetRelBaseOffset(hairUnitID, isYoung); |
| 55 | worldMatrix = Matrix::CreateTranslation(relOffset) * worldMatrix; |
| 56 | |
| 57 | // Use player's head bone orientation as base. |
| 58 | auto baseOrient = Geometry::ConvertDirectionToQuat(-Geometry::ConvertQuatToDirection(GetBoneOrientation(item, LM_HEAD))) * item.Pose.Orientation.ToQuaternion(); |
| 59 | |
| 60 | // Set position of base segment. |
| 61 | Segments[0].Position = worldMatrix.Translation(); |
| 62 | |
| 63 | if (!IsInitialized) |
| 64 | { |
| 65 | // Update segment positions. |
| 66 | for (int i = 0; i < Segments.size() - 1; i++) |
| 67 | { |
| 68 | auto& segment = Segments[i]; |
| 69 | auto& nextSegment = Segments[i + 1]; |
| 70 | |
| 71 | // NOTE: Joint offset determines segment length. |
| 72 | auto jointOffset = GetJointOffset(ObjectID, i, true); |
| 73 | |
| 74 | worldMatrix = Matrix::CreateTranslation(segment.Position); |
| 75 | worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * worldMatrix; |
| 76 | worldMatrix = Matrix::CreateTranslation(jointOffset) * worldMatrix; |
| 77 | |
| 78 | nextSegment.Position = worldMatrix.Translation(); |
| 79 | } |
| 80 | |
| 81 | IsInitialized = true; |
| 82 | } |
| 83 | else |
| 84 | { |
| 85 | // Get water height. |
| 86 | auto pos = item.Pose.Position + Vector3i(GetWaterProbeOffset(item)); |
| 87 | int roomNumber = item.RoomNumber; |
| 88 | int waterHeight = GetPointCollision(pos, roomNumber).GetWaterTopHeight(); |
| 89 | |
| 90 | // Get collision spheres. |
| 91 | auto spheres = GetSpheres(item); |
| 92 | |
| 93 | // Update segments. |
| 94 | for (int i = 1; i < Segments.size(); i++) |
| 95 | { |
| 96 | auto& segment = Segments[i]; |
| 97 | auto& prevSegment = Segments[i - 1]; |
nothing calls this directly
no test coverage detected