UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

126 lines (125 loc) 5.4 kB
import { Context } from "../../engine/engine_setup.js"; import { Behaviour } from "../Component.js"; import { type IPointerEventHandler, PointerEventData } from "./PointerEvents.js"; import { Raycaster } from "./Raycaster.js"; export declare enum EventSystemEvents { BeforeHandleInput = "BeforeHandleInput", AfterHandleInput = "AfterHandleInput" } export declare type AfterHandleInputEvent = { sender: EventSystem; args: PointerEventData; hasActiveUI: boolean; }; /** * @category User Interface * @group Components */ export declare class EventSystem extends Behaviour { static ensureUpdateMeshUI(instance: any, context: Context, force?: boolean): void; static markUIDirty(_context: Context): void; static createIfNoneExists(context: Context): void; static get(ctx: Context): EventSystem | null; /** Get the currently active event system */ static get instance(): EventSystem | null; private readonly raycaster; register(rc: Raycaster): void; unregister(rc: Raycaster): void; get hasActiveUI(): boolean; get isHoveringObjects(): boolean; awake(): void; start(): void; onEnable(): void; onDisable(): void; /** * all pointers that have pressed something * * key: pointerId * value: object that was pressed, data of the pointer event, handlers that are releavant to the event */ private pressedByID; /** * all hovered objects * * key: pointerId * value: object that is hovered, data of the pointer event */ private hoveredByID; onBeforeRender(): void; /** * Handle an pointer event from the input system */ private onPointerEvent; private readonly _sortedHits; /** * cache for objects that we want to raycast against. It's cleared before each call to performRaycast invoking raycasters */ private readonly _testObjectsCache; /** that's the raycaster that is CURRENTLY being used for raycasting (the shouldRaycastObject method uses this) */ private _currentlyActiveRaycaster; private _currentPointerEventName; /** * Checks if an object that we encounter has an event component and if it does, we add it to our objects cache * If it doesnt we tell our raycasting system to ignore it and continue in the child hierarchy * We do this to avoid raycasts against objects that are not going to be used by the event system * Because there's no component callback to be invoked anyways. * This is especially important to avoid expensive raycasts against SkinnedMeshes * * Further optimizations would be to check what type of event we're dealing with * For example if an event component has only an onPointerClick method we don't need to raycast during movement events * */ private shouldRaycastObject; private shouldRaycastObject_AddToYesCache; /** the raycast filter is always overriden */ private performRaycast; private assignHitInformation; private handleIntersections; private _sortingBuffer; private _noDepthTestingResults; private sortCandidates; private out; /** * Handle hit result by preparing all needed information before propagation. * Then calling propagate. */ private handleEventOnObject; /** * Propagate up in hiearchy and call the callback for each component that is possibly a handler */ private propagate; /** * Propagate up in hierarchy and call handlers based on the pointer event data */ private handleMainInteraction; /** Propagate up in hierarchy and call onPointerExit */ private propagatePointerExit; /** handles onPointerUp - this will also release the pointerCapture */ private invokeOnPointerUp; /** Responsible for invoking onPointerEnter (and updating onPointerExit). We invoke onPointerEnter once per active pointerId */ private handlePointerEnter; /** Responsible for invoking onPointerExit (and updating onPointerEnter). We invoke onPointerExit once per active pointerId */ private handlePointerExit; /** updates the pointer state list for a component * @param comp the component to update * @param pointerId the pointerId to update * @param symbol the symbol to use for the state * @param add if true, the pointerId is added to the state list, if false the pointerId will be removed */ private updatePointerState; /** the list of component handlers that requested pointerCapture for a specific pointerId */ private readonly _capturedPointer; /** check if the event was marked to be captured: if yes add the current component to the captured list */ private handlePointerCapture; /** removes the component from the pointer capture list */ releasePointerCapture(evt: PointerEventData, component: IPointerEventHandler): void; /** invoke the pointerMove event on all captured handlers */ private invokePointerCapture; private readonly pointerEnterSymbol; private readonly pointerExitSymbol; private isChild; private handleMeshUiObjectWithoutShadowDom; private currentActiveMeshUIComponents; private handleMeshUIIntersection; private resetMeshUIStates; private testIsVisible; }