Cockpit model occasionally becomes glued to the view at a random angle
MirceaKitsune opened this issue · comments
At random times the 1st person cockpit model becomes glued to the view at a bad angle: It will always rotate with the view instead of the ship, meaning middle-mouse-button dragging can no longer be used to look around inside it... further more it's badly rotated so you're stuck looking at the chair or window and can't even see outside any more. Fortunately the issue can be resolved by saving and reloading your save.
I don't yet know what exactly triggers this behavior, only that it happens rarely but does on occasion. I believe someone on Discord suggested it may be related to pausing / unpausing the time.
I observed this behavior both in the newest Pioneer release (20230203) as well as latest Git master. I'm running / compiling it on Linux (Manjaro). AMD graphics card using the default amdgpu driver.
Yeah, stick with latest master, it's where we prefer to do the bug hunting.
thanks for reporting
Updated:
Cockpit rotation doesn't update while the game is paused, both in pause menu and if PAUSED
button is pressed. I didn't notice if you press Debug Info
button the game becomes paused.
Original comment:
Always occurs if you press Debug Info
button in pause menu, but stops if you then pause and unpause. Also, cockpit rotation doesn't update while in pause menu.
Update 2
In this part of code in void ShipCockpit::Update(const Player *player, float timeStep)
in ShipCockpit.cpp
:
if (m_icc == nullptr) {
// I don't know where to put this
resetInternalCameraController();
}
there is no check if current CameraController
is InternalCameraController
so the game will try to interpret whatever type of CameraController
is now as InternalCameraController
. In return m_icc
becomes garbage object with invalid values. Adding this check before resetInternalCameraController();
:
if (Pi::game->GetWorldView()->shipView->GetCameraController()->GetType() != CameraController::INTERNAL)
{
return;
}
or this:
if (Pi::game->GetWorldView()->shipView->IsExteriorView())
{
return;
}
Will fix issue mentioned in the first update and possibly fix this whole issue. Will test more to see.
Update
This doesn't work if camera was in external or sidereal view beforehand, unfortunately.
Original comment
This happens, because in this line in void ShipCockpit::Update(const Player *player, float timeStep)
in ShipCockpit.cpp
:
vector3d rot_axis = cur_dir.Cross(m_dir).Normalized();
If cur_dir == m_dir, Cross
function would return zero vector, which can't be normalized.
To easily reproduce this behaviour:
- Load Save;
- Your game should be paused now, don't rotate camera;
- Unpause the game;
- Cockpit becomes glued, which can be fixed only, if your reload save or just uncheck/check cockpit option in the pause menu.
The solution is to create new variable vector_cross
and then check it's length. If the length is zero, don't normalize it, instead
just assign cur_dir to rot_axis:
// For yaw/pitch
vector3d vector_cross = cur_dir.Cross(m_dir);
vector3d rot_axis = cur_dir;
if (vector_cross.LengthSqr() != 0.0)
{
rot_axis = vector_cross.Normalized();
}