pioneerspacesim / pioneer

A game of lonely space adventure

Home Page:https://pioneerspacesim.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

Screenshot_20230905_024853

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.

commented

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:

  1. Load Save;
  2. Your game should be paused now, don't rotate camera;
  3. Unpause the game;
  4. 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();
}