Skip to content
This repository has been archived by the owner on Jul 27, 2021. It is now read-only.

fix: limit raycast queries per frame #627

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

oOZakMcKrackeNOo
Copy link
Contributor

What?

In order to prevent casting many raycasts on the same frame, one possible solution is to make query messages replace older ones each time they arrive to the client. But this approach leads to another problem: sometimes we need to be able to cast more than one ray per frame (i.e. a car that needs to cast three rays on the front to avoid colliding). To allow this, Raycast Instances come to the rescue: a raycast instance is a numeric id that identifies each query that we need to make each frame.

Why?

When casting raycasts continuously on each update iteration, several messages can accumulate in client messaging bus. This can lead to performance and user experience issues because raycasts may be calculated many times each frame when not needed. Also, other messages processing are contingent on how many queries are enqueued on the same bus, aggravating the issue.

Comment on lines 90 to 99
export interface IPhysicsCast {
hitFirst: (ray: Ray, hitCallback: (event: RaycastHitEntity) => void) => void
hitAll: (ray: Ray, hitCallback: (event: RaycastHitEntities) => void) => void
hitFirst(ray: Ray, hitCallback: (event: RaycastHitEntity) => void): void
hitAll(ray: Ray, hitCallback: (event: RaycastHitEntities) => void): void
hitFirst(ray: Ray, hitCallback: (event: RaycastHitEntity) => void, id: number): void
hitAll(ray: Ray, hitCallback: (event: RaycastHitEntities) => void, id: number): void
/** @internal */
hitFirstAvatar: (ray: Ray, hitCallback: (event: RaycastHitAvatar) => void) => void
hitFirstAvatar(ray: Ray, hitCallback: (event: RaycastHitAvatar) => void): void
/** @internal */
hitAllAvatars: (ray: Ray, hitCallback: (event: RaycastHitAvatars) => void) => void
hitAllAvatars(ray: Ray, hitCallback: (event: RaycastHitAvatars) => void): void
}
Copy link
Contributor

Choose a reason for hiding this comment

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

How about this notation instead?

  hitFirst(ray: Ray, hitCallback: (event: RaycastHitEntity) => void, id?: number): void
  hitAll(ray: Ray, hitCallback: (event: RaycastHitEntities) => void, id?: number): void
  /** @internal */
  hitFirstAvatar(ray: Ray, hitCallback: (event: RaycastHitAvatar) => void): void
  /** @internal */
  hitAllAvatars(ray: Ray, hitCallback: (event: RaycastHitAvatars) => void): void
}```

public hitFirst(ray: Ray, hitCallback: (event: RaycastHitEntity) => void) {
const queryId = uuid()
public hitFirst(ray: Ray, hitCallback: (event: RaycastHitEntity) => void, id?: number) {
const queryId = typeof id === 'number' ? 'rqhf' + id : uuid()
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we take the 'rqhf' and 'rqha' to a QueryType prefix enum?

Copy link
Contributor

@BrianAmadori BrianAmadori left a comment

Choose a reason for hiding this comment

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

Already requested this change in unity-client. But I'm repeating here:
in encodeSceneMessage under dcl.ts we could pre-pack the sceneId+tag in the tag field, avoiding the expensive StringBuilder call in unity side.

/**
* @internal
*/
export enum QueryPrefix {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to export this enum? If not needed, let's drop the export.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants