| 165 | } |
| 166 | |
| 167 | void LookCamera(ItemInfo& item, const CollisionInfo& coll) |
| 168 | { |
| 169 | constexpr auto POS_LERP_ALPHA = 0.25f; |
| 170 | constexpr auto COLL_PUSH = BLOCK(0.25f) - BLOCK(1 / 16.0f); |
| 171 | constexpr auto LOOK_AT_DIST = BLOCK(0.5f); |
| 172 | constexpr auto CAMERA_DIST_COEFF = 0.7f; |
| 173 | constexpr auto CAMERA_DIST_MAX = BLOCK(0.75f); |
| 174 | |
| 175 | const auto& player = GetLaraInfo(item); |
| 176 | |
| 177 | int verticalOffset = GetLookCameraVerticalOffset(item, coll); |
| 178 | auto pivotOffset = Vector3i(0, verticalOffset, 0); |
| 179 | |
| 180 | float idealDist = -std::max(Camera.targetDistance * CAMERA_DIST_COEFF, CAMERA_DIST_MAX); |
| 181 | |
| 182 | // Define absolute camera orientation. |
| 183 | auto orient = player.Control.Look.Orientation + |
| 184 | EulerAngles(item.Pose.Orientation.x, item.Pose.Orientation.y, 0) + |
| 185 | EulerAngles(0, Camera.targetAngle, 0); |
| 186 | orient.x = std::clamp(orient.x, LOOKCAM_ORIENT_CONSTRAINT.first.x, LOOKCAM_ORIENT_CONSTRAINT.second.x); |
| 187 | |
| 188 | // Determine base position. |
| 189 | bool isInSwamp = TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber); |
| 190 | auto basePos = Vector3i( |
| 191 | item.Pose.Position.x, |
| 192 | isInSwamp ? g_Level.Rooms[item.RoomNumber].TopHeight : item.Pose.Position.y, |
| 193 | item.Pose.Position.z); |
| 194 | |
| 195 | // Define landmarks. |
| 196 | auto pivotPos = Geometry::TranslatePoint(basePos, item.Pose.Orientation.y, pivotOffset); |
| 197 | auto idealPos = Geometry::TranslatePoint(pivotPos, orient, idealDist); |
| 198 | auto lookAtPos = Geometry::TranslatePoint(pivotPos, orient, LOOK_AT_DIST); |
| 199 | |
| 200 | // Determine best position. |
| 201 | auto origin = GameVector(pivotPos, GetPointCollision(item, item.Pose.Orientation.y, pivotOffset.z, pivotOffset.y).GetRoomNumber()); |
| 202 | auto target = GameVector(idealPos, GetPointCollision(origin.ToVector3i(), origin.RoomNumber, orient.ToDirection(), idealDist).GetRoomNumber()); |
| 203 | |
| 204 | // Handle room and object collisions. |
| 205 | LOSAndReturnTarget(&origin, &target, 0); |
| 206 | CameraCollisionBounds(&target, COLL_PUSH, true); |
| 207 | ItemsCollideCamera(); |
| 208 | |
| 209 | // Smoothly update camera position. |
| 210 | MoveCamera(&target, Camera.speed); |
| 211 | Camera.target = GameVector(Camera.target.ToVector3i() + (lookAtPos - Camera.target.ToVector3i()) * POS_LERP_ALPHA, item.RoomNumber); |
| 212 | |
| 213 | LookAt(&Camera, 0); |
| 214 | UpdateMikePos(item); |
| 215 | Camera.oldType = Camera.type; |
| 216 | } |
| 217 | |
| 218 | void LookAt(CAMERA_INFO* cam, short roll) |
| 219 | { |
no test coverage detected