Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Camera/Input locking API #4332

Merged
merged 35 commits into from
Jan 31, 2024

Conversation

onebeastchris
Copy link
Member

@onebeastchris onebeastchris commented Dec 8, 2023

Hey! This latest api PR of mine adds a few very cool Bedrock-exclusive features to the Geyser API: Cameras and Input locking!

This includes the ability to:

  • Lock the player into a perspective (first person/third person/third person front)
  • Send colored camera fades (in other terms, "cutscreens")
  • Camera movements/transitions

Additionally, this adds the following:

  • api to lock player inputs - camera, movement control, or both
  • exposes a Vector3f position in the GeyserPlayerEntity to be able to point cameras at them etc (Otherwise, extensions are pretty much locked out of using this new PR :/)

API Additions

GeyserConnection.class

  • @NonNull EntityData entities(); returns the EntityData class that contains entity methods. showEmote, entityByJavaId and playerEntity are exposed there and deprecated in GeyserConnection

  • @NonNull CameraData camera() returns the CameraData class that contains methods to control the camera. Fog, camera shake, and camera locking/the new camera stuff is found here.

api/bedrock/camera - Contains the new camera stuff

enum CameraEaseType contains ease types (https://easings.net/) that control how the camera is moved to the new position. These are hard-coded in cloudburst aswell, and you can't add custom ones

enum CameraPerspective - contains the possible forced perspectives (first person, third person, third person front)

interface CameraFade Allows creating a camera fade (also with builder).

interface CameraPosition Allows creating a camera position (with optional fading to position)

interface CameraData Contains the new camera methods:

  • @Nullable CameraPerspective forcedCameraPerspective(); - returns current forced CameraPerspective, or null if none is forced.

  • void forceCameraPerspective(@NonNull CameraPerspective perspective); - forces a CameraPerspective on the player, which can't be switched client-side.

  • void sendCameraFade(CameraFade fade); - Sends a CameraFade to the player

  • void sendCameraPosition(CameraPosition position); - Sends a camera position (can include movement animations by setting an easetype) to the player

  • void clearCameraInstructions(); - Resets/stops all camera instructions (fade, camera position, forced camera perspectives)

  • boolean isCameraLocked(); returns whether the camera is locked

  • boolean lockCamera(boolean lock, @NonNull UUID owner); allows someone to lock the camera - when locked, a player cannot look around until unlocked. The UUID is used to ensure that multiple api users can send lock/unlock requests as needed, without accidental unlocking

For documentation on camera fades and camera position (and their limitations), see the microsoft docs. Only difference - there isnt much point to allowing the creation of custom presets that extend existing ones imo, so i've created geyser:free_audio, geyser:free_effects and geyser:free_audio_effects to cover those 2 usecases too. Setting position/rotation defaults imo isnt really useful in our usage.

  • Added cloudburst math in the ap

GeyserPlayerEntity

  • added a Vector3f position(); method to get the player's current position

EntityData

Contains the entityByJavaId, showEmote, and playerEntity methods. The equivalents are deprecated in the GeyserConnection class

Internal changes

  • new CameraUtils class to store CameraPresets/NamedDefinitions
  • new bedrock/camera folder, no clue where else to put bedrock specific stuff like that in core

I'll update this PR description after the changes have been more finalized - in the current form, it already seems to work, but i'd expect that feedback will change it's structure a fair bit more.

RFC's:

  • Should we expose r/g/b individually in the fade, or maybe java.awt.Color instead? Uses java.awt.Color now
  • See above - exposing position -> exposing cloudburst math in api? done
  • Currently, forcing a player perspective takes in a CameraPerspective, which also contains the free perspective, but you cant actually set a free perspective there (since that would require a position). I could either remove free from the CameraPerspective - which then wouldnt properly show a forcedPerspective whenever the client is forced to a free perspective (aka, disconnected camera from the player set to basically anywhere)... idk, open for feedback on that one.
    Properly documented now.

Outlook:
The changes here could be used to allow geyser players to spectate entities. However, we must ensure that our usage of the camera positions would not interfere/be blocked by api - not sure how that would be handled correctly.

I'll release an extension to test these api additions in more detail in the coming days aswell.

If you read this, you're cool :p

@onebeastchris onebeastchris added PR: Feature When a PR implements a new feature API The issue/feature request relates to the Geyser API labels Dec 8, 2023
@onebeastchris
Copy link
Member Author

The api can be tested using an extension i quickly drafted up:
https://github.com/onebeastchris/CameraApiTestExtension

While making it i also found that we should expose the current GeyserPlayerEntity in a GeyserConnection, since otherwise it's not possible to use a fair bit of the api with extensions (specifically, accessing the exposed player position).

- Suppress constantconditions to enforce api
@onebeastchris onebeastchris added the PR: Needs review Indicates that a PR is functional and review-ready. label Dec 16, 2023
# Conflicts:
#	core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
Copy link

@Wolf2323 Wolf2323 left a comment

Choose a reason for hiding this comment

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

LGTM

I have reviewed the code and it looks like the way I want my code to be. So I give my approval and will now do some testing with the new API.

- include cloudburst math in api, drop custom Position.java class
- make CameraDefinition.java a subclass of CameraDefinitions.java
- Introduce a CameraExpansion api class to allow separation of Camera methods from the rest of the GeyserConnection api/impl in GeyserSession
- use Vector3f instead of position
- rename all XYZBuilders to just Builder (suggested by @Konicai)
- deprecate fog/camera shake in GeyserConnection and move to CameraExpansion
- move entitybyjavaid(), playerEntity(), and showEmote() to the new EntityExpansion stuff to keep GeyserConnection clean
 - add lockMovement() and isMovementLocked() to api
…d CameraData respectively

Created an impl directory to put api impls into
@Wolf2323
Copy link

I wanted to ask if we can expect to get this merged? And when can we expect this?

@onebeastchris onebeastchris merged commit f555dc0 into GeyserMC:master Jan 31, 2024
1 check passed
@onebeastchris onebeastchris deleted the camera-api branch February 28, 2024 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API The issue/feature request relates to the Geyser API PR: Feature When a PR implements a new feature PR: Needs review Indicates that a PR is functional and review-ready.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants