Facepunch / garrysmod-issues

Garry's Mod issue tracker
145 stars 56 forks source link

EyeAngles is wrong when sitting in a vehicle #1150

Closed Divran closed 3 years ago

Divran commented 10 years ago

So apparently ply:EyeAngles() is incorrect if you sit in a vehicle while its pitch or roll or both are nonzero.

EDIT: ply:GetAimVector() is also affected! This is likely because ply:GetAimVector() probably does ply:EyeAngles():Forward() internally.

To see the problem in action, use this Expression 2 code (or any similar Lua code - I'm only posting this because E2 is a very useful tool for debugging things like this)

@persist Seat:entity
if (first()) {
    holoCreate(1)
    holoScale(1,vec(2)/12)
    holoColor(1,vec(255,0,0))

    Seat = entity():isWeldedTo()
}

interval(10)
local Pos = rangerOffset(60000,Seat:driver():shootPos(),Seat:driver():eye()):position()
holoPos(1,Pos)

(E2's ply:eye() function uses GLua's ply:GetAimVector() function. It probably does ply:EyeAngles():Forward()) Spawn this chip on any vehicle, then rotate the vehicle so that its pitch or roll (or both) is not zero. Then sit in the vehicle and you'll clearly see that the hologram is not in your crosshairs, even though it should be.

The strange thing is, this only happens serverside. The clientside EyeAngles function works perfectly fine. It's only the serverside one that is broken.

From what I've heard, it's a problem with the Source engine's code, but I thought I'd report it here anyway in case there is anything you can do to fix it.

A guy over at wiremod.com says he's found the source of the problem, right here at the bottom of this file: http://hlssmod.net/he_code/game/server/hl2/vehicle_prisoner_pod.cpp

(And no, this issue does not only affect wiremod. Should be obvious, but I'll say it anyway)

EDIT: I'm no longer entirely sure if this problem is EyeAngles' fault or the vehicle camera's. In any case, the camera direction does not match up with EyeAngles when you rotate the vehicle, which is odd.

I found a possible fix

It is the Source engine's fault. The C function I linked earlier is most likely the cause. Here's a possible fix.

ply:EyeAngles() is NOT wrong. It is in fact the CAMERA that is angled wrong.

  1. CalcView in base gamemode receives the wrong angles from the server: https://github.com/garrynewman/garrysmod/blob/master/garrysmod/gamemodes/base/gamemode/cl_init.lua#L354
  2. Garry's third person vehicle CalcView uses fucked up these angles: https://github.com/garrynewman/garrysmod/blob/master/garrysmod/gamemodes/base/gamemode/cl_init.lua#L316

To fix all these problems, all you have to do is not use the angles the Source engine gives you. Instead, you use ply:EyeAngles() (probably have to WorldToLocalit) and voila, problem solved. That's third person fixed. Now you just have to use CalcView for first person as well, and that problem is also solved.

neico commented 9 years ago

Just stumbled onto this issue while working on a cam.Start3D2D which adjusts it's angle based on EyeAngles to draw a rotating text, makes me wonder if it's going to get fixed anytime soon...

willox commented 9 years ago

@neico Related or even same root cause as #1404

Divran commented 9 years ago

I've solved this problem in wire's camera controller. Take a look at this giant code, it's in there somewhere: https://github.com/wiremod/wire/blob/master/lua/entities/gmod_wire_cameracontroller.lua

robotboy655 commented 3 years ago

Little update: https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/server/hl2/vehicle_prisoner_pod.cpp#L722-L723

These 2 lines are the cause for this issue on the server (probably doesn't matter at all)

Clientside the issue is somewhere in this function, but I don't see it: https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/shared/vehicle_viewblend_shared.cpp#L299-L322

I think the idea there is to make the camera be more aligned with the horizon, while GetAimVector/EyeAngles simply (properly) adds the 2 entity angles.

thegrb93 commented 3 years ago

Can you replace it with how the client does it and see if it fixes the issue?

https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/client/hl2/c_vehicle_prisoner_pod.cpp#L187

thegrb93 commented 3 years ago

Looks like the server version tries to simplify things while the clientside uses the typical SharedVehicleViewSmoothing

robotboy655 commented 3 years ago

Can you replace it with how the client does it and see if it fixes the issue?

Tried it, didn't work and it couldn't considering what I said above. The only 2 ways to workaround this is to either change EyeAngles or get rid of the code that makes the camera more aligned with the horizon.

robotboy655 commented 3 years ago

Ok, it should be fixed for Jeeps, Airboats and the Prisoner Pods/Chairs. I have not tested other vehicles.

I have ended up making EyeAngles() report the correct position (as opposed to changing the vehicle view to match the old eyeangles direction) as it seems to be a better solution overall for aiming from cars and for driving around with a camera less glued to vehicle angles/position.

Divran commented 3 years ago

@robotboy655 see the referenced issue in wiremod above I currently don't have time to do any tests but I will when I can

EDIT: Issue has now been fixed, see referenced issue in wire repo above for more details

TiberiumFusion commented 2 years ago

Edited for clarity to reflect new info provided after posting this.

@robotboy655 Why was this issue closed? In the current version of gmod, EyeAngles returns data that is different from what one would expect.

Player:EyeAngles() returns angles that are relative to the vehicle's rotation. This contradicts the documentation, which claims that EyeAngles() "Returns...a world-oriented angle". Yes, the warning text "BUG This may return local angles in jeeps when used with Player:EnterVehicle." on the wiki page is still present, but this thread is closed. Considering this thread's title, "EyeAngles is wrong when sitting in a vehicle", it would stand to reason that the quoted warning text ought to be removed or edited to reflect new intended behavior (if that is indeed the case).

Addendum: It is very likely that the problem demonstrated below is different from the problem described by the OP. However, the outcome of both problems can be summarized by "EyeAngles is wrong when sitting in a vehicle" (thread title), and the solution that closed this thread (new LocalEyeAngles() method) returns identical data to EyeAngles() when sitting in a vehicle. With that considered, it seems like the issue demonstrated below is related to the issue described in the OP.

Demonstration

  1. Demo addon: vehicle_eye_angles_bug_demo.zip
  2. -noworkshop
  3. Observe your EyeAngles as visualized by the demo addon. Notice they are correct.
  4. Get in any vehicle (jeep, airboat, pod, seat) that is not perfectly aligned with worldspace +Y.
  5. Observe your EyeAngles. Notice that they are incorrect.
  6. Rotate the vehicle such that it faces +Y and get back in.
  7. Observe your EyeAngles. If you had perfectly aligned the vehicle along +Y, you will notice your EyeAngles are now correct.
  8. Also notice the janky shit that happens when getting in and out of a vehicle (strange eye angles and player direction abruptly changes).

Demo Video

Github's 2008 internet can't handle attachments over 10MB so please view the video on youtube.

Red is player:EyeAngles() Green is player:LocalEyeAngles() Blue is vehicle:LocalToWorldAngles(player:EyeAngles())

Environment

Protocol version 24
Exe version 2021.12.15 (garrysmod)
Exe build: 20:02:11 Dec 14 2021 (8438) (4000)
GMod version 2021.12.14, branch: unknown, multicore: 0
Windows 32bit

Same on whatever today's x86-64 is as well.

Kefta commented 2 years ago

Talking about Facepunch as a unified entity no longer makes (and never really made) sense for this game's development, and explains the lack of synchronicity between component parts.

TiberiumFusion commented 2 years ago

@Kefta That does explain the disconnects, but it does not validate them. I don't think you were implying that, but I suspect that many (including Facepunch themselves) believe as such.

I don't see anything nonsensical about regarding Facepunch as Facepunch, i.e. the organization of people who control, distribute, maintain and sell their product (gmod) commercially. It is quite normal to expect them to do the bare minimum of ensuring matching docs and code for their product. I don't care if they outsource their wiki to a small inner circle of community members who may or may not be privileged with source access. I don't have that access. I can't see into their walled garden, and neither can 99.99% of all other addons authors. Facepunch is the only entity on the planet who can produce accurate documentation for their product, so I expect them take responsibility for their own product and do as such.

Perhaps I am completely wrong and I can receive access to all sources for gmod just by asking nicely. If that is the case, then my point is moot, and I would love to know where I can find the complete source.

Kefta commented 2 years ago

The wiki is publicly editable - the entire effort of linking GitHub issues on wiki pages was started by me and a small group of active editors, and many pages remain outdated due to the original group who added them mostly moving on from GMod. This was never an official effort and does not represent Facepunch as an organization. Dylibs are still shipped on the main branch on Mac iirc so it's possible to reverse engineer the source without having to figure out symbols.

It's not wrong of you to assume it's Facepunch's responsibility to keep all this aligned/have some sort of regular process to make sure changes actually fix the bugs they were intending to, but it doesn't currently and probably will never. You have a greater chance of seeing this fixed by simply saying "This was not fixed" followed by minimal reproduction steps/code, which you did provide. Such is the reality of a game with one developer working on it, and is actively being pushed out the door with a newer product.

Divran commented 2 years ago

I am not agreeing or disagreeing here, merely stating facts.

All of the tests you mentioned were already performed by me and a few other people. It doesn't look like our tests from back then missed something that your tests didn't.

9 months ago I didn't care if the EyeAngles function behavior was reverted to what it was before this update, or if a new function was added with the behavior of the old EyeAngles, or whatever. The solution that ended up being implemented was to add a new function.

Unless there's a NEW problem that breaks the new LocalEyeAngles function once again? That would've been noticed immediately by people over in the wiremod community and I haven't received any reports so far.

Unless I'm remembering wrong, the "world oriented" problem has been a thing since the beginning of gmod. Or at least as far back as I can remember. The cam controller in wiremod has always used LocalToWorld to fix this. EDIT: actually after a quick check, in older versions of gmod, EyeAngles was global clientside but local serverside, so the server needed to use LocalToWorld and the client didn't. At least when inside vehicles.

The new problem that these talks fixed was the misalignment when the vehicle wasn't perfectly aligned to one of the cardinal directions.

EDIT 2: in the end I don't really care how it's solved, as long as there is a working solution.

FlorianLeChat commented 2 years ago

Player:EyeAngles() still returns angles that are relative to the vehicle's rotation. This contradicts the documentation, which claims that EyeAngles() "Returns...a world-oriented angle". Yes, the warning text "BUG This may return local angles in jeeps when used with Player:EnterVehicle." on the wiki page is still present, but this thread was closed 9 months ago. It is strange that the warning was not removed when the issue was allegedly "fixed".

The issue #2620 is still open and listed on the wiki because it seems its author has pointed out that the issue is not relevant to the current situation. If for some reason Rubat's fix has changed the way the function works then this should be fixed on the wiki. Even if before each update release he makes some changes on the wiki, there might be some oversights and I don't see how this can be detrimental to Facepunch, the wiki is open for everyone after all.

TiberiumFusion commented 2 years ago

@Kefta I occasionally mention this issue with Facepunch in hopes that others will agree and voice similar concern. Facepunch is an eccentric company and it may very well happen that they change someday.

@Divran Thanks for the clarification. Honestly, I did not create a gmod circa 2014 + wire circa 2014 test setup to validate the issue I experienced with the one you experienced. I was on the fence about opening a new issue that looked like a duplicate at first glance. However...

...GetAimVector/EyeAngles simply (properly) adds the 2 entity angles...

This description by rubat is what prompted me to put my findings in here. The issue you experienced seemed to be related to the quoted behavior, and the issue I experienced is surely due to the absence of it. It is strange that LocalEyeAngles and EyeAngles return identical data (per the issue I experienced) when sitting in a vehicle. Why introduce LocalEyeAngles() to get eye angles in parent entity space while EyeAngles() already does that? Both get the child entity angles and neither factors in the parent entity angles (when in a vehicle).

@FlorianLeChat 2620 is one of those issues with very little specifics and no code. Unless you are rubat, it's almost impossible to guess at exactly what the OP was describing (does he mean SetEyeAngles() is called with bad data? does he mean EyeAngles() start returning bad data? etc). The issue I experience may be related to it or even the same thing (or not related at all), but there's just not enough info to go on.

...there might be some oversights [on the wiki]...I don't see how this can be detrimental to Facepunch...

It's not. They will sell more gmod regardless of the wiki's accuracy. The problem is when something gets half-fixed, half-updated, half-changed, and then years go by... now this half-and-half behavior is the new "standard", and any future issue with it is much harder to work around. It's detrimental to addon authors.


Can an administrator split off my initial comment and the following comments into a new issue? It seems like the issue I experienced is related to this one and is not a duplicate, and the comments in question are just muddying up this thread.

Divran commented 2 years ago

It is strange that LocalEyeAngles and EyeAngles return identical data (per the issue I experienced) when sitting in a vehicle. Why introduce LocalEyeAngles() to get eye angles in parent entity space while EyeAngles() already does that? Both get the child entity angles and neither factors in the parent entity angles (when in a vehicle).

I don't know if something has changed in the 9 months since this issue was closed, but that was definitely not the case back then. robotboy modified the behavior of EyeAngles about 9 and a bit months ago, which broke it for the specific use case that I needed (maybe for all uses but I only cared about ours), which prompted us to reopen this ticket and then after some back and forth LocalEyeAngles was added. The discussion is all still there, including a few videos, in the linked issue on the wire github. Go read it and watch the videos if you want to know more.

in case you missed the link https://github.com/wiremod/wire/issues/2168

EDIT: it's also possible that different vehicles behave differently. Did you only try it with the jeep? Or did you also try the "vehicles" that are just chairs/seats? Because those are the ones I tested it with. Almost nobody who uses the camera controller in wiremod is going to be using a jeep, after all. They'll be using their own vehicle contraption with just a chair strapped to it.

TiberiumFusion commented 2 years ago

@Divran That is one long thread. I don't have time to read it now but I will check it later.

EDIT: it's also possible that different vehicles behave differently. Did you only try it with the jeep?

The demo video I provided only shows the jeep, but I also tested the airboat, pod, and seats. They all have the same behavior. LocalEyeAngles() and EyeAngles() return the same angle. You can verify this with the demo addon I provided.

demo-ss-all-vehicles

Red is player:EyeAngles() Green is player:LocalEyeAngles() Blue is vehicle:LocalToWorldAngles(player:EyeAngles())

Because EyeAngles and LocalEyeAngles return identical values, the red and green indicators would normally overlap. They are not overlapping, however, because the green indicator is drawn with an extra 45 degrees of roll. This is purely visual and does not affect the real values.

Almost nobody who uses the camera controller in wiremod is going to be using a jeep, after all. They'll be using their own vehicle contraption with just a chair strapped to it.

That makes sense, but I'm not a wire guy so I'm not familiar with that side of things. I ran into this issue with EyeAngles while making a plain old vehicle (i.e. vehicle scripts) with some guns.

robotboy655 commented 2 years ago

It was fixed but had to be rolled back because it broke too many mods relying on this incorrect behavior. The fix instead was only applied to Player.GetAimVector which fixes weapon aiming while in a vehicle and doesn't break anything. I have no plans in changing Player.EyeAngles for the aforementioned reason.