Skip to content

Fix moving NPC vehicle pitch not synced - #1249

Open
Fanorisky wants to merge 4 commits into
openmultiplayer:masterfrom
Fanorisky:master
Open

Fix moving NPC vehicle pitch not synced#1249
Fanorisky wants to merge 4 commits into
openmultiplayer:masterfrom
Fanorisky:master

Conversation

@Fanorisky

Copy link
Copy Markdown

rotation sent in driver sync previously only used yaw, so moving npc vehicles looked flat instead of tilting toward their direction of travel.
now pitch is calculated from position vs target position while moving_, then combined with yaw before sync.

@eakwarp

eakwarp commented Aug 7, 2026

Copy link
Copy Markdown

@AmyrAhmady maybe its time?)
I tested the current implementation in all possible variants, and it's either this or NPC_SetQuaternion (from #1206 ) is needed

@AmyrAhmady AmyrAhmady left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments and some empty line breaks are removed for some reason

Comment thread Server/Components/NPCs/NPC/npc.cpp
Comment thread Server/Components/NPCs/NPC/npc.cpp Outdated
@Fanorisky
Fanorisky requested a review from AmyrAhmady August 7, 2026 18:23
@AmyrAhmady

Copy link
Copy Markdown
Member

instead of doing things raw, can you use

const glm::vec3 delta = targetPosition_ - position_;

const float pitch = -atan2(delta.z, glm::length(glm::vec2(delta)));
const float yaw = glm::yaw(rotation_.q);

rotation_.q = glm::angleAxis(pitch, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(yaw, glm::vec3(0.0f, 0.0f, 1.0f));

and put it in NPC::move instead of resetting it every sync packet broadcasting

@Fanorisky

Copy link
Copy Markdown
Author

@AmyrAhmady thanks, that's much cleaner .
adopted it

@AmyrAhmady AmyrAhmady left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure you test it again in game after you made new changes, this would be my final change request and if you confirm it works in your test cases, I'll accept it

{
front = (pos - position) / distance;
auto rotation = getRotation().ToEuler();
rotation.x = 0.0f; // Discard the pitch a previous drive move may have baked in, it would skew the facing angle

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this doesn't really change much, but since this line is meant to be for vehicles/driving only, let's move it in the if code block down there you made for moveType_ == NPCMoveType_Drive.

But remember it should be rotation_.x when you do.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GTAQuat only has a glm::quat q member, so rotation_.x won't compile. also, rotation_.q.x is a quaternion component, not an euler angle.

but I think this line actually belongs in the non-drive path rather than the drive one. inside the drive block, the quaternion gets overwritten completely by the angleAxis composition, so a stale pitch there shouldn't really matter.

the case that actually needs it is when an NPC drives uphill and then gets told to walk. move() calls removeFromVehicle() itself, and sendFootSync() writes the full quaternion, so the ped keeps walking around tilted by 26.5° even on flat ground.

moving it into the if would also mean adding a matching else, which basically just means having the same line in both branches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants