@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
TypeScript
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;
}