Skip to content

Vanilla-like camera#894

Merged
Try merged 30 commits intomasterfrom
camera-dev
Feb 4, 2026
Merged

Vanilla-like camera#894
Try merged 30 commits intomasterfrom
camera-dev

Conversation

@Try
Copy link
Owner

@Try Try commented Jan 31, 2026

This PR seek to approximate behavior of vanilla camera.

Camera definition, provided by scripts. Can vary between default/inventory/melee/mobsi

class CCamSys definition in scripts
class CCamSys 
{
  // angles -180 to 180 
  float bestRange;
  float minRange;
  float maxRange;
  float bestElevation;
  float minElevation;
  float maxElevation;
  float bestAzimuth;
  float minAzimuth;
  float maxAzimuth;
  float bestRotZ;
  float minRotZ;
  float maxRotZ;
  float rotOffsetX;
  float rotOffsetY;
  float rotOffsetZ;
  float targetOffsetX;
  float targetOffsetY;
  float targetOffsetZ;
  
  // dynamic 
  float veloTrans;  // velocity while easing   to best position
  float veloRot;    // velocity while rotating to best orientation
  	  
  int   translate;  // rotate around target, 1: on, 0:off
  int   rotate;     // rotate around target, 1: on, 0:off
  int   collision;  // disable collision for this mode (ideal pos must be near player)
};

Understanding so far:

image
  • target is following hero, with optional inertia (sometimes reffed as :"leash" mechanic).
  • origin desired position is computed from target, as shown on illustration.
    • "origin" actual position interpolated from to "desired position", with velo_trans speed
    • "origin" actual position is used to compute view-matrix
  • "View direction" is sum of "View base direction" and rotOffset* angles. Gray on illustration.
    • "View base direction" computed as "look at" (similar to gluLookAt) to "Target". Green on illustration.
    • Non-interpolated, but "feels" smooth due to interpolation of origin
Vanilla OpenGothic
image image

Note: due to interpolated origin + "lookAt" mechanic:

  • range to player is slightly (300 -> 327 cm) increasing
  • azimuth seem to gradually losing 3 deg (30 -> 27) during running, for unknown reason.

Parameters bestRange / minRange / maxRange,

Measured in meters and we seem to have no issues with range. Distance counted from player position(aka target), plus targetOffset. Offset vector is based on camera angle, except rotOffset*.
In default camera bestRange = 300, what is consistent with "range to player" measured in debug mode, when player as PC_HERO. However this value is differed in case of large monsters. Troll is measured to have "range to player" = 400.

Parameters bestElevation / bestAzimuth

Those are define default camera rotation in Euler-angles.

Parameters minElevation / maxElevation and minAzimuth / maxAzimuth

Appears to be unused. At least camera rotation is not restricted by this in vanilla.

Parameters bestRotZ / minRotZ / maxRotZ.

Unknown. Always zero, in scripting.

Parameters rotOffsetX / rotOffsetY / rotOffsetZ.

Offset that applied to camera rotation.

Parameters targetOffsetX / targetOffsetX / targetOffsetX.

Offset to point that camera follows. Defined in "local" coordinate system, that accounts for hero rotation around OY. Other rotations are not considered.
Subject to "camera collision". Example:

Vanilla OpenGothic
image image

Parameter veloTrans

Affect interpolation of actual and desired position of origin.
Here recording of veloTrans = 1, and offset from target = ~2000

velotrans.mp4

Parameter veloRot

Speed of camera rotation. Similar issue as with veloTrans - mysterious applicability and unit of measurement.
When tested on toggling inventory on/off:

  • Parameter rotOffset clearly not snapped to new value, when changing camera, but interpolated to match new value.
  • Players input for rotation, seemingly not interacting with rotOffset.

Vanilla:

Video.Project.mp4

OpenGothic:

og_inventory.mp4

Rotation (player driven)

Measured, by spinning character on keyboard. On mouse - assume same value, since it's impossible to get reproducible testing.
Note: rotation by keyboard has 2 speed bands: 100deg/sec is default and in combat mode - 200deg/sec

Vanilla OpenGothic
image image

Interacts with "leash" mechanic - target point is not aligned between vanilla and OG.

@Nindaleth
Copy link
Contributor

Inventory transition from 180 state to default non-inventory. It's visible, that distance of camera to player changes, as-if camera passes thru players position. However our model doesn't account for that.

Here's my attempt at recording this in 60 FPS:

2026-02-01_16-23-14.trimmed.mp4

Here's another attempt - phone-made slow motion recording of the screen:

VID_20260201_163201928.mp4.2.mp4

@Try
Copy link
Owner Author

Try commented Feb 1, 2026

Thanks for testing @Nindaleth

Here's my attempt at recording this in 60 FPS

Yes, I have it. For me, it takes a DX7 over DX9 emulator + DX9 is emulated in windows. A mess, but good enough for the footage.

I've push quite a different model in cee3bb3: it interpolates origin position, computes angles, as-if camera has to have hero in the center, and offsets angles by rotOffset*.

TLDL: inventory transition should match now.

@Nindaleth
Copy link
Contributor

inventory transition should match now

Tried it and it seems to match for me too , very cool! The little things do add up, it's very nice.

I also didn't see any more glitching camera in dialogs on a quick test.

One issue that I discovered by accident: If you jump from a too high place and fall flat on the face, but survive the fall, don't get up and instead move the camera above the hero and let go of the mouse. In a moment the camera will start rotating on its own, presumably triggered by something in the animation.

@Try
Copy link
Owner Author

Try commented Feb 2, 2026

In a moment the camera will start rotating on its own, presumably triggered by something in the animation.

Can you please clarify that part? AFAIK in vanilla death camera can also behave weird..

@Nindaleth
Copy link
Contributor

Can you please clarify that part? AFAIK in vanilla death camera can also behave weird..

When giving 04cf899 a super quick test, I'm not observing the issue any longer.

@Nindaleth
Copy link
Contributor

Nindaleth commented Feb 3, 2026

I tried another quick test of the current state of the PR (6dff2a7), the camera feels like it's always been like this, nothing to re-learn/re-adapt to, I really like it! If you merged today, I wouldn't complain at all. Actually quite the opposite, I will take a Windows CI build the first chance I have and give it to my friend for another round of tests to see if I can sway him to the OpenGothic side this time 😄

One more thing I've noticed, not pushing for it really, just something I think is also camera-related. There are a few differences in how the F and R keys are handled - most of them welcome upgrades of the original, to be honest, with two exceptions:

R key

When running and "looking behind", the healthbar of anyone in front of the hero is shown in the original too, but not the text labels. This has an unideal consequence in OpenGothic of also showing text for things like "To the temple square" signs.

F key

Currently I guess the camera (vertical) angle is preserved on toggle while I would like the position of stuff on the screen to be preserved. Let me give you an example - in the usual 3rd person camera case, if I stand in front of the door so that it is in the middle of my physical monitor and switch into 1st person, I'm looking at the ground instead. If I then look at the door so that it is in the middle of my screen and switch back into 3rd person, I'm looking at the sky instead.

I think I like that the angle is preserved on toggling the views in OpenGothic. The original always resets to a default angle on any toggle which is annoying on 1st->3rd person toggle including some weird camera movement, but I have to admit the original's toggle from 3rd->1st person absolutely nails what I expect to see from the 1st person perspective.

Maybe keep preserving the (vertical) angle but add an offset so that both perspectives are still useful?

@Try
Copy link
Owner Author

Try commented Feb 3, 2026

R key

A bug. Should be fixed now.

F key

I'll do it tomorrow - basically FP camera doesn't interact well with "camera-mode", while de-factor is a camera mode, just special one.

I think I like that the angle is preserved on toggling the views in OpenGothic

In some cases game have to do it (such as dialogs/mobsi). OG keep angles only if 'regular' camera transitions into another 'regular'. Regular is default-one, with-weapon and inventory-mode.

@Try
Copy link
Owner Author

Try commented Feb 4, 2026

@Nindaleth

Both issue should be resolved now. One other small thing: in windows build I'm now discarding mouse events on queue level, in setCursorPosition. This is required to avoid excessive moue events between mouse-event generation and event processing.

Unfortunately X11 implementation is not done for it - may I add you for review, once I have something working?

@Nindaleth
Copy link
Contributor

Can confirm, both F and R keys now work as good as vanilla or even slightly better IMHO. Thanks for all your efforts, @Try!

Unfortunately X11 implementation is not done for it - may I add you for review, once I have something working?

Sure, loop me in, I can check for any sudden behavior changes on my side.

@Try Try merged commit d5d2ed4 into master Feb 4, 2026
8 of 9 checks passed
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.

2 participants