@onerjs/core 8.51.6 → 8.51.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cameras/inputMapper.js +13 -9
- package/Cameras/inputMapper.js.map +1 -1
- package/Engines/AbstractEngine/abstractEngine.views.pure.js.map +1 -1
- package/Engines/AbstractEngine/abstractEngine.views.types.d.ts +2 -1
- package/Engines/AbstractEngine/abstractEngine.views.types.js.map +1 -1
- package/Engines/abstractEngine.pure.js +11 -4
- package/Engines/abstractEngine.pure.js.map +1 -1
- package/Engines/engine.pure.d.ts +23 -0
- package/Engines/engine.pure.js +96 -1
- package/Engines/engine.pure.js.map +1 -1
- package/Engines/nativeEngine.pure.d.ts +4 -0
- package/Engines/nativeEngine.pure.js +6 -0
- package/Engines/nativeEngine.pure.js.map +1 -1
- package/Engines/thinNativeEngine.pure.d.ts +21 -0
- package/Engines/thinNativeEngine.pure.js +119 -4
- package/Engines/thinNativeEngine.pure.js.map +1 -1
- package/Engines/webgpuEngine.pure.d.ts +21 -0
- package/Engines/webgpuEngine.pure.js +46 -1
- package/Engines/webgpuEngine.pure.js.map +1 -1
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.d.ts +5 -0
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.js +8 -0
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.js.map +1 -0
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.d.ts +278 -0
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js +718 -0
- package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js.map +1 -0
- package/Materials/GaussianSplatting/pure.d.ts +1 -0
- package/Materials/GaussianSplatting/pure.js +1 -0
- package/Materials/GaussianSplatting/pure.js.map +1 -1
- package/Materials/Textures/internalTexture.d.ts +11 -1
- package/Materials/Textures/internalTexture.js +23 -0
- package/Materials/Textures/internalTexture.js.map +1 -1
- package/Materials/index.d.ts +1 -0
- package/Materials/index.js +1 -0
- package/Materials/index.js.map +1 -1
- package/Materials/pure.d.ts +1 -0
- package/Materials/pure.js +1 -0
- package/Materials/pure.js.map +1 -1
- package/Meshes/GaussianSplatting/gaussianSplattingDebugger.d.ts +7 -0
- package/Meshes/GaussianSplatting/gaussianSplattingDebugger.js +8 -0
- package/Meshes/GaussianSplatting/gaussianSplattingDebugger.js.map +1 -0
- package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.d.ts +147 -0
- package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js +257 -0
- package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js.map +1 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +11 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +31 -0
- package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
- package/Meshes/GaussianSplatting/pure.d.ts +1 -0
- package/Meshes/GaussianSplatting/pure.js +1 -0
- package/Meshes/GaussianSplatting/pure.js.map +1 -1
- package/Meshes/abstractMesh.pure.js +3 -0
- package/Meshes/abstractMesh.pure.js.map +1 -1
- package/Meshes/index.d.ts +1 -0
- package/Meshes/index.js +1 -0
- package/Meshes/index.js.map +1 -1
- package/Meshes/pure.d.ts +1 -0
- package/Meshes/pure.js +1 -0
- package/Meshes/pure.js.map +1 -1
- package/Misc/tools.pure.js +1 -1
- package/Misc/tools.pure.js.map +1 -1
- package/Shaders/ShadersInclude/gaussianSplatting.js +33 -10
- package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/Shaders/gaussianSplatting.vertex.js +20 -1
- package/Shaders/gaussianSplatting.vertex.js.map +1 -1
- package/Shaders/picking.fragment.js +4 -1
- package/Shaders/picking.fragment.js.map +1 -1
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +33 -10
- package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
- package/ShadersWGSL/gaussianSplatting.vertex.js +21 -2
- package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
- package/SmartAssets/index.d.ts +2 -2
- package/SmartAssets/index.js +2 -1
- package/SmartAssets/index.js.map +1 -1
- package/SmartAssets/pure.d.ts +1 -1
- package/SmartAssets/pure.js +2 -1
- package/SmartAssets/pure.js.map +1 -1
- package/SmartAssets/smartAssetManager.js +9 -0
- package/SmartAssets/smartAssetManager.js.map +1 -1
- package/package.json +1 -1
- package/scene.pure.js.map +1 -1
package/Cameras/inputMapper.js
CHANGED
|
@@ -142,18 +142,22 @@ export class InputMapper {
|
|
|
142
142
|
// from a string-keyed loop. The runtime check is harmless: irrelevant-for-this-source
|
|
143
143
|
// fields are undefined on both entry and conditions and skip the early return.
|
|
144
144
|
const e = entry;
|
|
145
|
-
for (const
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
for (const key of Object.keys(conditions)) {
|
|
146
|
+
const condValue = conditions[key];
|
|
147
|
+
if (condValue === undefined) {
|
|
148
|
+
continue;
|
|
148
149
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
if (key === "modifiers") {
|
|
151
|
+
const entryMods = (e.modifiers ?? {});
|
|
152
|
+
for (const modKey of Object.keys(condValue)) {
|
|
153
|
+
if (condValue[modKey] !== undefined && entryMods[modKey] === undefined) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
155
156
|
}
|
|
156
157
|
}
|
|
158
|
+
else if (e[key] === undefined) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
157
161
|
}
|
|
158
162
|
return true;
|
|
159
163
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputMapper.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/inputMapper.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Physical input source that generated an interaction.\r\n */\r\nexport type InputSource = \"pointer\" | \"wheel\" | \"touch\" | \"keyboard\";\r\n\r\n/**\r\n * Modifier key state, shared across input sources that support modifiers.\r\n */\r\nexport type InputModifiers = {\r\n /** Ctrl key pressed */\r\n ctrl?: boolean;\r\n /** Shift key pressed */\r\n shift?: boolean;\r\n /** Alt key pressed */\r\n alt?: boolean;\r\n};\r\n\r\n// ── Per-source condition shapes ────────────────────────────────────\r\n\r\n/**\r\n * Conditions for pointer inputs.\r\n */\r\nexport type PointerConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right). Omit to match any button. */\r\n button?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for mouse wheel inputs.\r\n */\r\nexport type WheelConditions = {\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for touch inputs.\r\n */\r\nexport type TouchConditions = {\r\n /** Number of active touch points. Omit to match any count. */\r\n touchCount?: number;\r\n};\r\n\r\n/**\r\n * Conditions for keyboard inputs.\r\n */\r\nexport type KeyboardConditions = {\r\n /** Key code of the current key being resolved. Omit to match any key. */\r\n key?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n// ── Per-source inputMap entry types ────────────────────────────────\r\n\r\n/**\r\n * Mapping rule for pointer (mouse button) inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type PointerInputMapEntry<TInteraction extends string = string> = {\r\n source: \"pointer\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X (horizontal / yaw) component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y (vertical / pitch) component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & PointerConditions;\r\n\r\n/**\r\n * Mapping rule for mouse wheel inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type WheelInputMapEntry<TInteraction extends string = string> = {\r\n source: \"wheel\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n} & WheelConditions;\r\n\r\n/**\r\n * Mapping rule for touch inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type TouchInputMapEntry<TInteraction extends string = string> = {\r\n source: \"touch\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & TouchConditions;\r\n\r\n/**\r\n * Mapping rule for keyboard inputs.\r\n * The `key` field on the entry supports a single key code or an array of key codes for matching.\r\n * When resolving, the condition's `key` is checked against the entry's `key` value(s).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type KeyboardInputMapEntry<TInteraction extends string = string> = {\r\n /** Discriminator: keyboard input source */\r\n source: \"keyboard\";\r\n /** Interaction type to dispatch when this entry matches */\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Key code filter(s). Supports a single code or an array. Omit to match any key. */\r\n key?: number | number[];\r\n /** Modifier keys that must be active for this entry to match. Omit to match regardless of modifiers. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * A single mapping rule: source + optional conditions → interaction type.\r\n * The inputMap is an ordered array on the movement class; first matching entry wins.\r\n * The interaction string should match a handler property name on the camera's movement subclass.\r\n *\r\n * Discriminated union by `source` — only fields relevant to that source are available.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InputMapEntry<TInteraction extends string = string> =\r\n | PointerInputMapEntry<TInteraction>\r\n | WheelInputMapEntry<TInteraction>\r\n | TouchInputMapEntry<TInteraction>\r\n | KeyboardInputMapEntry<TInteraction>;\r\n\r\n/**\r\n * Flat conditions object passed to resolveInteraction().\r\n * Only the fields relevant to the source type need to be set.\r\n * Per-source condition types (PointerConditions, KeyboardConditions, etc.) are subtypes\r\n * of this and should be used at call sites for clarity.\r\n */\r\nexport type InputConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right) */\r\n button?: number;\r\n /** Current modifier key state */\r\n modifiers?: InputModifiers;\r\n /** Number of active touch points */\r\n touchCount?: number;\r\n /** Key code of the current key being resolved */\r\n key?: number;\r\n};\r\n\r\n/**\r\n * Extracts the string-typed interaction names from a handlers object type.\r\n * Equivalent to `keyof THandlers & string` — filters out symbol/number keys.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InteractionName<THandlers> = keyof THandlers & string;\r\n\r\n/**\r\n * Generic input-to-interaction mapper that resolves physical input events to semantic interaction types\r\n * and dispatches them to typed handlers.\r\n *\r\n * `InputMapper` is not tied to cameras — any object that needs a configurable, prioritized\r\n * mapping from physical inputs (pointer, keyboard, wheel, touch) to named interactions can use it.\r\n *\r\n * The mapper holds an ordered `inputMap` array. When `resolveInteraction` is called, the first\r\n * entry whose source and conditions match the current input wins. More specific entries (with more\r\n * conditions like button, key, modifiers) should be placed before less specific ones; use `addEntry`\r\n * to auto-insert based on specificity.\r\n *\r\n * @typeParam THandlers - Object type whose keys are the valid interaction type strings and values\r\n * are the handler functions/objects for each interaction (e.g. `ArcRotateHandlers`).\r\n * Interaction types are derived as `InteractionName<THandlers>`.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class InputMapper<THandlers extends Record<string, unknown>> {\r\n /**\r\n * Ordered list of input-to-interaction mapping rules. First matching entry wins.\r\n */\r\n public inputMap: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n\r\n /**\r\n * Interaction handlers keyed by interaction type.\r\n * Override individual handlers to customize behavior without changing input mapping.\r\n */\r\n public readonly handlers: THandlers;\r\n\r\n /**\r\n * Creates a new InputMapper.\r\n * @param handlers - The interaction handlers, keyed by interaction type.\r\n * @param createDefaultEntries - Optional factory that returns the default inputMap entries.\r\n * Called by `resetInputMap()` and during construction. When omitted, the default map is empty.\r\n */\r\n constructor(handlers: THandlers, createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[]) {\r\n this.handlers = handlers;\r\n this._createDefaultEntries = createDefaultEntries;\r\n this.resetInputMap();\r\n }\r\n\r\n private _createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[];\r\n\r\n /**\r\n * Resolves a physical input event to a matching inputMap entry.\r\n * Iterates the inputMap in order; the first entry whose source and conditions match wins.\r\n * @param source - The physical input source (e.g. \"pointer\", \"keyboard\")\r\n * @param currentConditions - Conditions to match against, specific to the source type\r\n * @returns The matched InputMapEntry, or null if no entry matches\r\n */\r\n public resolveInteraction(source: \"pointer\", currentConditions?: InputConditions): PointerInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"wheel\", currentConditions?: InputConditions): WheelInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"touch\", currentConditions?: InputConditions): TouchInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"keyboard\", currentConditions?: InputConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null {\r\n for (const entry of this.inputMap) {\r\n if (entry.source === source && this._entryMatches(entry, currentConditions)) {\r\n return entry;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Restores the inputMap to the default entries provided at construction time.\r\n * If no factory was provided, resets to an empty array.\r\n */\r\n public resetInputMap(): void {\r\n this.inputMap = this._createDefaultEntries?.() ?? [];\r\n }\r\n\r\n /**\r\n * Finds the first inputMap entry matching the given source, interaction, and optional entry conditions.\r\n * Useful for modifying entry properties (e.g. sensitivity) without rebuilding the entire inputMap.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns The matching entry, or undefined if not found\r\n */\r\n public getEntry(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined {\r\n // Manual loop instead of `inputMap.find(arrow)` to avoid per-call closure allocation;\r\n // this is hit per pointer-move from multi-touch panning paths.\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n return e;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Finds all inputMap entries matching the given source, interaction, and optional entry conditions.\r\n * Useful for bulk updates when more than one physical input maps to the same interaction.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns All matching entries, in inputMap order\r\n */\r\n public getEntries(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[] {\r\n const matches: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n matches.push(e);\r\n }\r\n }\r\n return matches;\r\n }\r\n\r\n /**\r\n * Adds an entry to the inputMap at the correct position based on specificity.\r\n * More specific entries (with more conditions like button, key, modifiers) are placed\r\n * before less specific ones, ensuring they match first. Among equally specific entries,\r\n * the new entry is placed after existing ones.\r\n * @param entry - The entry to add\r\n */\r\n public addEntry(entry: InputMapEntry<InteractionName<THandlers>>): void {\r\n const score = this._entrySpecificity(entry);\r\n let insertIndex = this.inputMap.length;\r\n for (let i = 0; i < this.inputMap.length; i++) {\r\n if (this._entrySpecificity(this.inputMap[i]) < score) {\r\n insertIndex = i;\r\n break;\r\n }\r\n }\r\n this.inputMap.splice(insertIndex, 0, entry);\r\n }\r\n\r\n /**\r\n * Sets the interaction for the input combination described by `conditions`. If an\r\n * existing entry maps that exact combination, its `interaction` is updated in place;\r\n * otherwise a new entry is inserted via {@link addEntry}.\r\n *\r\n * To force an update on every matching entry use {@link setInteractions}; to address\r\n * an individual entry beyond the first, look it up via {@link getEntries} and assign\r\n * `entry.interaction` directly.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions describing the input combination (button, modifiers, key, etc.)\r\n * @param interaction - The interaction to assign / insert\r\n * @returns true (the mapping is always made effective)\r\n */\r\n public setInteraction(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): boolean {\r\n // resolveInteraction returns the first entry that fires for `conditions` (so its\r\n // conditions are no stricter than the request). If that entry also covers every\r\n // condition present in the request, it's an exact match — mutate. Otherwise it's\r\n // broader (or nothing matches): add a more-specific entry so we don't clobber the\r\n // broader one.\r\n const entry = this.resolveInteraction(source, conditions);\r\n if (entry && this._entryCoversAllConditionsOf(entry, conditions)) {\r\n entry.interaction = interaction;\r\n return true;\r\n }\r\n this.addEntry({ source, ...(conditions ?? {}), interaction } as InputMapEntry<InteractionName<THandlers>>);\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true when `entry` constrains every field that `conditions` specifies — i.e.\r\n * `entry` covers all of the request's conditions. Used by {@link setInteraction} as one\r\n * half of the \"exactly as specific\" check: combined with {@link resolveInteraction}'s\r\n * guarantee that the returned entry is no *stricter* than the request, a true result\r\n * here means `entry` and `conditions` constrain the same fields, and mutating\r\n * `entry.interaction` is safe.\r\n *\r\n * On its own this predicate does not exclude entries that are stricter than `conditions`\r\n * (those would also trivially cover every field present in `conditions`); callers must\r\n * rely on the upstream resolve step to rule them out.\r\n *\r\n * `InputConditions` is a flat type covering all source-specific fields (`button`, `key`,\r\n * `touchCount`, `modifiers`); for any given source the irrelevant fields are `undefined`\r\n * on both `entry` and `conditions`, so checking them all is harmless.\r\n * @param entry - The matched inputMap entry to test\r\n * @param conditions - The conditions the caller supplied to `setInteraction`\r\n * @returns true if `entry` covers every condition present in `conditions`\r\n */\r\n private _entryCoversAllConditionsOf(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n // `as any` here because `entry` is a discriminated union and TypeScript can't narrow it\r\n // from a string-keyed loop. The runtime check is harmless: irrelevant-for-this-source\r\n // fields are undefined on both entry and conditions and skip the early return.\r\n const e = entry as any;\r\n for (const field of [\"button\", \"key\", \"touchCount\"] as const) {\r\n if (conditions[field] !== undefined && e[field] === undefined) {\r\n return false;\r\n }\r\n }\r\n if (conditions.modifiers) {\r\n const entryMods = e.modifiers ?? {};\r\n for (const key of Object.keys(conditions.modifiers) as (keyof InputModifiers)[]) {\r\n if (conditions.modifiers[key] !== undefined && entryMods[key] === undefined) {\r\n return false;\r\n }\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Changes the interaction for every inputMap entry matching the given source and conditions.\r\n * Useful when more than one entry maps to the same physical input (e.g. duplicate bindings,\r\n * or several keys aliased to the same action) and all of them should be remapped together.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions to match (button, modifiers, key, etc.). Uses the same\r\n * event-resolution semantics as {@link resolveInteraction}: omitted entry\r\n * condition fields are treated as wildcards and will match.\r\n * @param interaction - The new interaction to assign to every matched entry\r\n * @returns The number of entries that were updated\r\n */\r\n public setInteractions(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): number {\r\n let count = 0;\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const entry = arr[i];\r\n if (entry.source === source && this._entryMatches(entry, conditions)) {\r\n entry.interaction = interaction;\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n private _entryMatches(entry: InputMapEntry<InteractionName<THandlers>>, currentConditions?: InputConditions): boolean {\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (entry.button !== undefined && entry.button !== currentConditions?.button) {\r\n return false;\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"wheel\":\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"touch\":\r\n if (entry.touchCount !== undefined && entry.touchCount !== currentConditions?.touchCount) {\r\n return false;\r\n }\r\n return true;\r\n case \"keyboard\":\r\n if (entry.key !== undefined) {\r\n if (Array.isArray(entry.key) ? entry.key.indexOf(currentConditions?.key ?? -1) === -1 : entry.key !== currentConditions?.key) {\r\n return false;\r\n }\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n }\r\n }\r\n\r\n private _entryConditionsMatch(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n\r\n // NOTE: Uses the `\"key\" in conditions` form rather than `conditions.key !== undefined`\r\n // so that callers can explicitly target entries with no constraint via\r\n // `getEntries({ button: undefined })` — i.e. \"find catch-all entries that don't\r\n // require a specific button\". `!== undefined` would silently ignore a deliberate\r\n // `undefined` and behave like the property was omitted, which would be wrong here.\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (\"button\" in conditions && entry.button !== conditions.button) {\r\n return false;\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"wheel\":\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"touch\":\r\n return !(\"touchCount\" in conditions) || entry.touchCount === conditions.touchCount;\r\n case \"keyboard\":\r\n if (\"key\" in conditions) {\r\n if (entry.key === undefined) {\r\n return conditions.key === undefined;\r\n }\r\n if (conditions.key === undefined || (Array.isArray(entry.key) ? entry.key.indexOf(conditions.key) === -1 : entry.key !== conditions.key)) {\r\n return false;\r\n }\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n }\r\n }\r\n\r\n private _entrySpecificity(entry: InputMapEntry<InteractionName<THandlers>>): number {\r\n let score = 0;\r\n if (\"button\" in entry && entry.button !== undefined) {\r\n score++;\r\n }\r\n if (\"key\" in entry && entry.key !== undefined) {\r\n score++;\r\n }\r\n if (\"touchCount\" in entry && entry.touchCount !== undefined) {\r\n score++;\r\n }\r\n if (\"modifiers\" in entry && entry.modifiers) {\r\n score++;\r\n }\r\n return score;\r\n }\r\n\r\n private _matchModifiers(entryModifiers?: InputModifiers, currentModifiers?: InputModifiers): boolean {\r\n if (!entryModifiers) {\r\n return true;\r\n }\r\n if (entryModifiers.ctrl !== undefined && entryModifiers.ctrl !== (currentModifiers?.ctrl ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.shift !== undefined && entryModifiers.shift !== (currentModifiers?.shift ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.alt !== undefined && entryModifiers.alt !== (currentModifiers?.alt ?? false)) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _entryModifiersMatch(entryModifiers?: InputModifiers, conditionsModifiers?: InputModifiers): boolean {\r\n if (!conditionsModifiers) {\r\n return !entryModifiers;\r\n }\r\n\r\n const hasModifierConditions = conditionsModifiers.ctrl !== undefined || conditionsModifiers.shift !== undefined || conditionsModifiers.alt !== undefined;\r\n if (!hasModifierConditions) {\r\n return !entryModifiers || (entryModifiers.ctrl === undefined && entryModifiers.shift === undefined && entryModifiers.alt === undefined);\r\n }\r\n\r\n if (conditionsModifiers.ctrl !== undefined && entryModifiers?.ctrl !== conditionsModifiers.ctrl) {\r\n return false;\r\n }\r\n if (conditionsModifiers.shift !== undefined && entryModifiers?.shift !== conditionsModifiers.shift) {\r\n return false;\r\n }\r\n if (conditionsModifiers.alt !== undefined && entryModifiers?.alt !== conditionsModifiers.alt) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"inputMapper.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/inputMapper.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\n/**\r\n * Physical input source that generated an interaction.\r\n */\r\nexport type InputSource = \"pointer\" | \"wheel\" | \"touch\" | \"keyboard\";\r\n\r\n/**\r\n * Modifier key state, shared across input sources that support modifiers.\r\n */\r\nexport type InputModifiers = {\r\n /** Ctrl key pressed */\r\n ctrl?: boolean;\r\n /** Shift key pressed */\r\n shift?: boolean;\r\n /** Alt key pressed */\r\n alt?: boolean;\r\n};\r\n\r\n// ── Per-source condition shapes ────────────────────────────────────\r\n\r\n/**\r\n * Conditions for pointer inputs.\r\n */\r\nexport type PointerConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right). Omit to match any button. */\r\n button?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for mouse wheel inputs.\r\n */\r\nexport type WheelConditions = {\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * Conditions for touch inputs.\r\n */\r\nexport type TouchConditions = {\r\n /** Number of active touch points. Omit to match any count. */\r\n touchCount?: number;\r\n};\r\n\r\n/**\r\n * Conditions for keyboard inputs.\r\n */\r\nexport type KeyboardConditions = {\r\n /** Key code of the current key being resolved. Omit to match any key. */\r\n key?: number;\r\n /** Modifier key state. Only specified keys are checked; omitted = don't-care. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n// ── Per-source inputMap entry types ────────────────────────────────\r\n\r\n/**\r\n * Mapping rule for pointer (mouse button) inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type PointerInputMapEntry<TInteraction extends string = string> = {\r\n source: \"pointer\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X (horizontal / yaw) component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y (vertical / pitch) component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & PointerConditions;\r\n\r\n/**\r\n * Mapping rule for mouse wheel inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type WheelInputMapEntry<TInteraction extends string = string> = {\r\n source: \"wheel\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n} & WheelConditions;\r\n\r\n/**\r\n * Mapping rule for touch inputs.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type TouchInputMapEntry<TInteraction extends string = string> = {\r\n source: \"touch\";\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Optional per-axis override for the X component. Falls back to `sensitivity` if unset. */\r\n sensitivityX?: number;\r\n /** Optional per-axis override for the Y component. Falls back to `sensitivity` if unset. */\r\n sensitivityY?: number;\r\n} & TouchConditions;\r\n\r\n/**\r\n * Mapping rule for keyboard inputs.\r\n * The `key` field on the entry supports a single key code or an array of key codes for matching.\r\n * When resolving, the condition's `key` is checked against the entry's `key` value(s).\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type KeyboardInputMapEntry<TInteraction extends string = string> = {\r\n /** Discriminator: keyboard input source */\r\n source: \"keyboard\";\r\n /** Interaction type to dispatch when this entry matches */\r\n interaction: TInteraction;\r\n /** Multiplier applied to input deltas before passing to the handler. Default is 1. */\r\n sensitivity?: number;\r\n /** Key code filter(s). Supports a single code or an array. Omit to match any key. */\r\n key?: number | number[];\r\n /** Modifier keys that must be active for this entry to match. Omit to match regardless of modifiers. */\r\n modifiers?: InputModifiers;\r\n};\r\n\r\n/**\r\n * A single mapping rule: source + optional conditions → interaction type.\r\n * The inputMap is an ordered array on the movement class; first matching entry wins.\r\n * The interaction string should match a handler property name on the camera's movement subclass.\r\n *\r\n * Discriminated union by `source` — only fields relevant to that source are available.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InputMapEntry<TInteraction extends string = string> =\r\n | PointerInputMapEntry<TInteraction>\r\n | WheelInputMapEntry<TInteraction>\r\n | TouchInputMapEntry<TInteraction>\r\n | KeyboardInputMapEntry<TInteraction>;\r\n\r\n/**\r\n * Flat conditions object passed to resolveInteraction().\r\n * Only the fields relevant to the source type need to be set.\r\n * Per-source condition types (PointerConditions, KeyboardConditions, etc.) are subtypes\r\n * of this and should be used at call sites for clarity.\r\n */\r\nexport type InputConditions = {\r\n /** Mouse button (0=left, 1=middle, 2=right) */\r\n button?: number;\r\n /** Current modifier key state */\r\n modifiers?: InputModifiers;\r\n /** Number of active touch points */\r\n touchCount?: number;\r\n /** Key code of the current key being resolved */\r\n key?: number;\r\n};\r\n\r\n/**\r\n * Extracts the string-typed interaction names from a handlers object type.\r\n * Equivalent to `keyof THandlers & string` — filters out symbol/number keys.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport type InteractionName<THandlers> = keyof THandlers & string;\r\n\r\n/**\r\n * Generic input-to-interaction mapper that resolves physical input events to semantic interaction types\r\n * and dispatches them to typed handlers.\r\n *\r\n * `InputMapper` is not tied to cameras — any object that needs a configurable, prioritized\r\n * mapping from physical inputs (pointer, keyboard, wheel, touch) to named interactions can use it.\r\n *\r\n * The mapper holds an ordered `inputMap` array. When `resolveInteraction` is called, the first\r\n * entry whose source and conditions match the current input wins. More specific entries (with more\r\n * conditions like button, key, modifiers) should be placed before less specific ones; use `addEntry`\r\n * to auto-insert based on specificity.\r\n *\r\n * @typeParam THandlers - Object type whose keys are the valid interaction type strings and values\r\n * are the handler functions/objects for each interaction (e.g. `ArcRotateHandlers`).\r\n * Interaction types are derived as `InteractionName<THandlers>`.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class InputMapper<THandlers extends Record<string, unknown>> {\r\n /**\r\n * Ordered list of input-to-interaction mapping rules. First matching entry wins.\r\n */\r\n public inputMap: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n\r\n /**\r\n * Interaction handlers keyed by interaction type.\r\n * Override individual handlers to customize behavior without changing input mapping.\r\n */\r\n public readonly handlers: THandlers;\r\n\r\n /**\r\n * Creates a new InputMapper.\r\n * @param handlers - The interaction handlers, keyed by interaction type.\r\n * @param createDefaultEntries - Optional factory that returns the default inputMap entries.\r\n * Called by `resetInputMap()` and during construction. When omitted, the default map is empty.\r\n */\r\n constructor(handlers: THandlers, createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[]) {\r\n this.handlers = handlers;\r\n this._createDefaultEntries = createDefaultEntries;\r\n this.resetInputMap();\r\n }\r\n\r\n private _createDefaultEntries?: () => InputMapEntry<InteractionName<THandlers>>[];\r\n\r\n /**\r\n * Resolves a physical input event to a matching inputMap entry.\r\n * Iterates the inputMap in order; the first entry whose source and conditions match wins.\r\n * @param source - The physical input source (e.g. \"pointer\", \"keyboard\")\r\n * @param currentConditions - Conditions to match against, specific to the source type\r\n * @returns The matched InputMapEntry, or null if no entry matches\r\n */\r\n public resolveInteraction(source: \"pointer\", currentConditions?: InputConditions): PointerInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"wheel\", currentConditions?: InputConditions): WheelInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"touch\", currentConditions?: InputConditions): TouchInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: \"keyboard\", currentConditions?: InputConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null;\r\n public resolveInteraction(source: InputSource, currentConditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | null {\r\n for (const entry of this.inputMap) {\r\n if (entry.source === source && this._entryMatches(entry, currentConditions)) {\r\n return entry;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Restores the inputMap to the default entries provided at construction time.\r\n * If no factory was provided, resets to an empty array.\r\n */\r\n public resetInputMap(): void {\r\n this.inputMap = this._createDefaultEntries?.() ?? [];\r\n }\r\n\r\n /**\r\n * Finds the first inputMap entry matching the given source, interaction, and optional entry conditions.\r\n * Useful for modifying entry properties (e.g. sensitivity) without rebuilding the entire inputMap.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns The matching entry, or undefined if not found\r\n */\r\n public getEntry(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined;\r\n public getEntry(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>> | undefined {\r\n // Manual loop instead of `inputMap.find(arrow)` to avoid per-call closure allocation;\r\n // this is hit per pointer-move from multi-touch panning paths.\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n return e;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Finds all inputMap entries matching the given source, interaction, and optional entry conditions.\r\n * Useful for bulk updates when more than one physical input maps to the same interaction.\r\n * @param source - The physical input source to match\r\n * @param interaction - The interaction type to match\r\n * @param conditions - Optional entry conditions to match. Omitted condition fields are ignored.\r\n * @returns All matching entries, in inputMap order\r\n */\r\n public getEntries(source: \"pointer\", interaction: InteractionName<THandlers>, conditions?: PointerConditions): PointerInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"wheel\", interaction: InteractionName<THandlers>, conditions?: WheelConditions): WheelInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"touch\", interaction: InteractionName<THandlers>, conditions?: TouchConditions): TouchInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: \"keyboard\", interaction: InteractionName<THandlers>, conditions?: KeyboardConditions): KeyboardInputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[];\r\n public getEntries(source: InputSource, interaction: InteractionName<THandlers>, conditions?: InputConditions): InputMapEntry<InteractionName<THandlers>>[] {\r\n const matches: InputMapEntry<InteractionName<THandlers>>[] = [];\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const e = arr[i];\r\n if (e.source === source && e.interaction === interaction && this._entryConditionsMatch(e, conditions)) {\r\n matches.push(e);\r\n }\r\n }\r\n return matches;\r\n }\r\n\r\n /**\r\n * Adds an entry to the inputMap at the correct position based on specificity.\r\n * More specific entries (with more conditions like button, key, modifiers) are placed\r\n * before less specific ones, ensuring they match first. Among equally specific entries,\r\n * the new entry is placed after existing ones.\r\n * @param entry - The entry to add\r\n */\r\n public addEntry(entry: InputMapEntry<InteractionName<THandlers>>): void {\r\n const score = this._entrySpecificity(entry);\r\n let insertIndex = this.inputMap.length;\r\n for (let i = 0; i < this.inputMap.length; i++) {\r\n if (this._entrySpecificity(this.inputMap[i]) < score) {\r\n insertIndex = i;\r\n break;\r\n }\r\n }\r\n this.inputMap.splice(insertIndex, 0, entry);\r\n }\r\n\r\n /**\r\n * Sets the interaction for the input combination described by `conditions`. If an\r\n * existing entry maps that exact combination, its `interaction` is updated in place;\r\n * otherwise a new entry is inserted via {@link addEntry}.\r\n *\r\n * To force an update on every matching entry use {@link setInteractions}; to address\r\n * an individual entry beyond the first, look it up via {@link getEntries} and assign\r\n * `entry.interaction` directly.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions describing the input combination (button, modifiers, key, etc.)\r\n * @param interaction - The interaction to assign / insert\r\n * @returns true (the mapping is always made effective)\r\n */\r\n public setInteraction(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): boolean {\r\n // resolveInteraction returns the first entry that fires for `conditions` (so its\r\n // conditions are no stricter than the request). If that entry also covers every\r\n // condition present in the request, it's an exact match — mutate. Otherwise it's\r\n // broader (or nothing matches): add a more-specific entry so we don't clobber the\r\n // broader one.\r\n const entry = this.resolveInteraction(source, conditions);\r\n if (entry && this._entryCoversAllConditionsOf(entry, conditions)) {\r\n entry.interaction = interaction;\r\n return true;\r\n }\r\n this.addEntry({ source, ...(conditions ?? {}), interaction } as InputMapEntry<InteractionName<THandlers>>);\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true when `entry` constrains every field that `conditions` specifies — i.e.\r\n * `entry` covers all of the request's conditions. Used by {@link setInteraction} as one\r\n * half of the \"exactly as specific\" check: combined with {@link resolveInteraction}'s\r\n * guarantee that the returned entry is no *stricter* than the request, a true result\r\n * here means `entry` and `conditions` constrain the same fields, and mutating\r\n * `entry.interaction` is safe.\r\n *\r\n * On its own this predicate does not exclude entries that are stricter than `conditions`\r\n * (those would also trivially cover every field present in `conditions`); callers must\r\n * rely on the upstream resolve step to rule them out.\r\n *\r\n * `InputConditions` is a flat type covering all source-specific fields (`button`, `key`,\r\n * `touchCount`, `modifiers`); for any given source the irrelevant fields are `undefined`\r\n * on both `entry` and `conditions`, so checking them all is harmless.\r\n * @param entry - The matched inputMap entry to test\r\n * @param conditions - The conditions the caller supplied to `setInteraction`\r\n * @returns true if `entry` covers every condition present in `conditions`\r\n */\r\n private _entryCoversAllConditionsOf(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n // `as any` here because `entry` is a discriminated union and TypeScript can't narrow it\r\n // from a string-keyed loop. The runtime check is harmless: irrelevant-for-this-source\r\n // fields are undefined on both entry and conditions and skip the early return.\r\n const e = entry as any;\r\n for (const key of Object.keys(conditions) as (keyof InputConditions)[]) {\r\n const condValue = conditions[key];\r\n if (condValue === undefined) {\r\n continue;\r\n }\r\n if (key === \"modifiers\") {\r\n const entryMods = (e.modifiers ?? {}) as InputModifiers;\r\n for (const modKey of Object.keys(condValue) as (keyof InputModifiers)[]) {\r\n if ((condValue as InputModifiers)[modKey] !== undefined && entryMods[modKey] === undefined) {\r\n return false;\r\n }\r\n }\r\n } else if (e[key] === undefined) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Changes the interaction for every inputMap entry matching the given source and conditions.\r\n * Useful when more than one entry maps to the same physical input (e.g. duplicate bindings,\r\n * or several keys aliased to the same action) and all of them should be remapped together.\r\n * @param source - The physical input source to match\r\n * @param conditions - Conditions to match (button, modifiers, key, etc.). Uses the same\r\n * event-resolution semantics as {@link resolveInteraction}: omitted entry\r\n * condition fields are treated as wildcards and will match.\r\n * @param interaction - The new interaction to assign to every matched entry\r\n * @returns The number of entries that were updated\r\n */\r\n public setInteractions(source: InputSource, conditions: InputConditions | undefined, interaction: InteractionName<THandlers>): number {\r\n let count = 0;\r\n const arr = this.inputMap;\r\n for (let i = 0; i < arr.length; i++) {\r\n const entry = arr[i];\r\n if (entry.source === source && this._entryMatches(entry, conditions)) {\r\n entry.interaction = interaction;\r\n count++;\r\n }\r\n }\r\n return count;\r\n }\r\n\r\n private _entryMatches(entry: InputMapEntry<InteractionName<THandlers>>, currentConditions?: InputConditions): boolean {\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (entry.button !== undefined && entry.button !== currentConditions?.button) {\r\n return false;\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"wheel\":\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n case \"touch\":\r\n if (entry.touchCount !== undefined && entry.touchCount !== currentConditions?.touchCount) {\r\n return false;\r\n }\r\n return true;\r\n case \"keyboard\":\r\n if (entry.key !== undefined) {\r\n if (Array.isArray(entry.key) ? entry.key.indexOf(currentConditions?.key ?? -1) === -1 : entry.key !== currentConditions?.key) {\r\n return false;\r\n }\r\n }\r\n return this._matchModifiers(entry.modifiers, currentConditions?.modifiers);\r\n }\r\n }\r\n\r\n private _entryConditionsMatch(entry: InputMapEntry<InteractionName<THandlers>>, conditions?: InputConditions): boolean {\r\n if (!conditions) {\r\n return true;\r\n }\r\n\r\n // NOTE: Uses the `\"key\" in conditions` form rather than `conditions.key !== undefined`\r\n // so that callers can explicitly target entries with no constraint via\r\n // `getEntries({ button: undefined })` — i.e. \"find catch-all entries that don't\r\n // require a specific button\". `!== undefined` would silently ignore a deliberate\r\n // `undefined` and behave like the property was omitted, which would be wrong here.\r\n switch (entry.source) {\r\n case \"pointer\":\r\n if (\"button\" in conditions && entry.button !== conditions.button) {\r\n return false;\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"wheel\":\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n case \"touch\":\r\n return !(\"touchCount\" in conditions) || entry.touchCount === conditions.touchCount;\r\n case \"keyboard\":\r\n if (\"key\" in conditions) {\r\n if (entry.key === undefined) {\r\n return conditions.key === undefined;\r\n }\r\n if (conditions.key === undefined || (Array.isArray(entry.key) ? entry.key.indexOf(conditions.key) === -1 : entry.key !== conditions.key)) {\r\n return false;\r\n }\r\n }\r\n return !(\"modifiers\" in conditions) || this._entryModifiersMatch(entry.modifiers, conditions.modifiers);\r\n }\r\n }\r\n\r\n private _entrySpecificity(entry: InputMapEntry<InteractionName<THandlers>>): number {\r\n let score = 0;\r\n if (\"button\" in entry && entry.button !== undefined) {\r\n score++;\r\n }\r\n if (\"key\" in entry && entry.key !== undefined) {\r\n score++;\r\n }\r\n if (\"touchCount\" in entry && entry.touchCount !== undefined) {\r\n score++;\r\n }\r\n if (\"modifiers\" in entry && entry.modifiers) {\r\n score++;\r\n }\r\n return score;\r\n }\r\n\r\n private _matchModifiers(entryModifiers?: InputModifiers, currentModifiers?: InputModifiers): boolean {\r\n if (!entryModifiers) {\r\n return true;\r\n }\r\n if (entryModifiers.ctrl !== undefined && entryModifiers.ctrl !== (currentModifiers?.ctrl ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.shift !== undefined && entryModifiers.shift !== (currentModifiers?.shift ?? false)) {\r\n return false;\r\n }\r\n if (entryModifiers.alt !== undefined && entryModifiers.alt !== (currentModifiers?.alt ?? false)) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n private _entryModifiersMatch(entryModifiers?: InputModifiers, conditionsModifiers?: InputModifiers): boolean {\r\n if (!conditionsModifiers) {\r\n return !entryModifiers;\r\n }\r\n\r\n const hasModifierConditions = conditionsModifiers.ctrl !== undefined || conditionsModifiers.shift !== undefined || conditionsModifiers.alt !== undefined;\r\n if (!hasModifierConditions) {\r\n return !entryModifiers || (entryModifiers.ctrl === undefined && entryModifiers.shift === undefined && entryModifiers.alt === undefined);\r\n }\r\n\r\n if (conditionsModifiers.ctrl !== undefined && entryModifiers?.ctrl !== conditionsModifiers.ctrl) {\r\n return false;\r\n }\r\n if (conditionsModifiers.shift !== undefined && entryModifiers?.shift !== conditionsModifiers.shift) {\r\n return false;\r\n }\r\n if (conditionsModifiers.alt !== undefined && entryModifiers?.alt !== conditionsModifiers.alt) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstractEngine.views.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.views.pure.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAK7D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;GAGG;AACH,MAAM,OAAO,UAAU;CAkBtB;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACvC,IAAI,WAAW,EAAE,CAAC;QACd,OAAO;IACX,CAAC;IACD,WAAW,GAAG,IAAI,CAAC;IAEnB,gEAAgE;IAChE,MAAM,4BAA4B,GAAG,IAAI,UAAU,EAAc,CAAC;IAElE,gEAAgE;IAChE,MAAM,2BAA2B,GAAG,IAAI,UAAU,EAAc,CAAC;IAEjE,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,SAAS,EAAE,8BAA8B,EAAE;QAC5E,GAAG,EAAE;YACD,OAAO,4BAA4B,CAAC;QACxC,CAAC;KACJ,CAAC,CAAC;IAEH,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,SAAS,EAAE,6BAA6B,EAAE;QAC3E,GAAG,EAAE;YACD,OAAO,2BAA2B,CAAC;QACvC,CAAC;KACJ,CAAC,CAAC;IAEH,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,SAAS,EAAE,cAAc,EAAE;QAC5D,GAAG,EAAE;YACD,OAAO,IAAI,CAAC,aAAa,CAAC;QAC9B,CAAC;QACD,GAAG,EAAE,UAAgC,KAAkB;YACnD,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;gBAC/B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC3B,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAClC,CAAC;QACL,CAAC;KACJ,CAAC,CAAC;IAEH,cAAc,CAAC,SAAS,CAAC,eAAe,GAAG;QACvC,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC1D,CAAC,CAAC;IAEN,cAAc,CAAC,SAAS,CAAC,YAAY,GAAG,UACpC,MAAyB,EACzB,MAA0B,EAC1B,eAAyB,EACzB,YAAyC;QAEzC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QACpB,CAAC;QAEG,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC/C,IAAI,YAAY,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC;YAClC,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;QACxC,CAAC;QAEL,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,CAAC;QACjI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,IAAI,YAAY,EAAE,CAAC;YACf,YAAY,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE;gBAChC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;QACP,CAAC;QAEG,OAAO,OAAO,CAAC;IACnB,CAAC,CAAC;IAEF,cAAc,CAAC,SAAS,CAAC,cAAc,GAAG,UAAU,MAAyB;QACzE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAEvC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACf,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAChC,CAAC;gBACD,MAAM;YACV,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC;IAEF,cAAc,CAAC,SAAS,CAAC,eAAe,GAAG,UAAU,IAAgB;QACjE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAG,CAAC;QAE1C,4BAA4B,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,aAAa,GAAqB,IAAI,CAAC;QAC3C,IAAI,cAAc,GAAuB,IAAI,CAAC;QAC9C,IAAI,KAAK,GAAoB,IAAI,CAAC;QAClC,IAAI,MAAM,EAAE,CAAC;YACT,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAEzE,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC;YACnC,cAAc,GAAG,KAAK,CAAC,aAAa,CAAC;YAErC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACJ,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC;gBAC5B,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC/B,CAAC;QACL,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACJ,YAAY;YACZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAE5E,MAAM,WAAW,GAAG,KAAK,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC;YAC3I,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC;gBAC3D,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;gBACrB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;gBACvB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAChC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,mBAAmB;QACnB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,iBAAiB;QACjB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAEhC,UAAU;QACV,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,aAAa,GAAG,cAAc,CAAC;YACrC,KAAK,CAAC,YAAY,GAAG,aAAa,CAAC;QACvC,CAAC;QACD,2BAA2B,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC;IAEF,cAAc,CAAC,SAAS,CAAC,YAAY,GAAG;QACpC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAEzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,gBAAgB,CAAC;QACrB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAChB,SAAS;YACb,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,oEAAoE;YACpE,IAAI,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC/B,gBAAgB,GAAG,IAAI,CAAC;gBACxB,SAAS;YACb,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC;QAED,IAAI,gBAAgB,EAAE,CAAC;YACnB,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC1C,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC;AACN,CAAC","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Camera } from \"../../Cameras/camera.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\n/**\r\n * Class used to define an additional view for the engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/multiCanvas\r\n */\r\nexport class EngineView {\r\n /**\r\n * A randomly generated unique id\r\n */\r\n readonly id: string;\r\n /** Defines the canvas where to render the view */\r\n target: HTMLCanvasElement;\r\n /**\r\n * Defines an optional camera or array of cameras used to render the view (will use active camera / cameras else)\r\n * Support for array of cameras @since\r\n */\r\n camera?: Camera | Camera[];\r\n /** Indicates if the destination view canvas should be cleared before copying the parent canvas. Can help if the scene clear color has alpha < 1 */\r\n clearBeforeCopy?: boolean;\r\n /** Indicates if the view is enabled (true by default) */\r\n enabled: boolean;\r\n /** Defines a custom function to handle canvas size changes. (the canvas to render into is provided to the callback) */\r\n customResize?: (canvas: HTMLCanvasElement) => void;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineViews.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineViews(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const OnBeforeViewRenderObservable = new Observable<EngineView>();\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const OnAfterViewRenderObservable = new Observable<EngineView>();\r\n\r\n Object.defineProperty(AbstractEngine.prototype, \"onBeforeViewRenderObservable\", {\r\n get: function (this: AbstractEngine) {\r\n return OnBeforeViewRenderObservable;\r\n },\r\n });\r\n\r\n Object.defineProperty(AbstractEngine.prototype, \"onAfterViewRenderObservable\", {\r\n get: function (this: AbstractEngine) {\r\n return OnAfterViewRenderObservable;\r\n },\r\n });\r\n\r\n Object.defineProperty(AbstractEngine.prototype, \"inputElement\", {\r\n get: function (this: AbstractEngine) {\r\n return this._inputElement;\r\n },\r\n set: function (this: AbstractEngine, value: HTMLElement) {\r\n if (this._inputElement !== value) {\r\n this._inputElement = value;\r\n this._onEngineViewChanged?.();\r\n }\r\n },\r\n });\r\n\r\n AbstractEngine.prototype.getInputElement = function (): Nullable<HTMLElement> {\r\n return this.inputElement || this.getRenderingCanvas();\r\n };\r\n\r\nAbstractEngine.prototype.registerView = function (\r\n canvas: HTMLCanvasElement,\r\n camera?: Camera | Camera[],\r\n clearBeforeCopy?: boolean,\r\n customResize?: EngineView[\"customResize\"]\r\n): EngineView {\r\n if (!this.views) {\r\n this.views = [];\r\n }\r\n\r\n for (const view of this.views) {\r\n if (view.target === canvas) {\r\n return view;\r\n }\r\n }\r\n\r\n const masterCanvas = this.getRenderingCanvas();\r\n if (masterCanvas) {\r\n canvas.width = masterCanvas.width;\r\n canvas.height = masterCanvas.height;\r\n }\r\n\r\n const newView = { target: canvas, camera, clearBeforeCopy, enabled: true, id: (Math.random() * 100000).toFixed(), customResize };\r\n this.views.push(newView);\r\n if (customResize) {\r\n customResize(canvas);\r\n }\r\n if (camera && !Array.isArray(camera)) {\r\n camera.onDisposeObservable.add(() => {\r\n this.unRegisterView(canvas);\r\n });\r\n }\r\n\r\n return newView;\r\n };\r\n\r\n AbstractEngine.prototype.unRegisterView = function (canvas: HTMLCanvasElement): AbstractEngine {\r\n if (!this.views || this.views.length === 0) {\r\n return this;\r\n }\r\n\r\n for (const view of this.views) {\r\n if (view.target === canvas) {\r\n const index = this.views.indexOf(view);\r\n\r\n if (index !== -1) {\r\n this.views.splice(index, 1);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n\r\n AbstractEngine.prototype._renderViewStep = function (view: EngineView): boolean {\r\n const canvas = view.target;\r\n const context = canvas.getContext(\"2d\");\r\n if (!context) {\r\n return true;\r\n }\r\n const parent = this.getRenderingCanvas()!;\r\n\r\n OnBeforeViewRenderObservable.notifyObservers(view);\r\n const camera = view.camera;\r\n let previewCamera: Nullable<Camera> = null;\r\n let previewCameras: Nullable<Camera[]> = null;\r\n let scene: Nullable<Scene> = null;\r\n if (camera) {\r\n scene = Array.isArray(camera) ? camera[0].getScene() : camera.getScene();\r\n\r\n previewCamera = scene.activeCamera;\r\n previewCameras = scene.activeCameras;\r\n\r\n if (Array.isArray(camera)) {\r\n scene.activeCameras = camera;\r\n } else {\r\n scene.activeCamera = camera;\r\n scene.activeCameras = null;\r\n }\r\n }\r\n this.activeView = view;\r\n\r\n if (view.customResize) {\r\n view.customResize(canvas);\r\n } else {\r\n // Set sizes\r\n const width = Math.floor(canvas.clientWidth / this._hardwareScalingLevel);\r\n const height = Math.floor(canvas.clientHeight / this._hardwareScalingLevel);\r\n\r\n const dimsChanged = width !== canvas.width || parent.width !== canvas.width || height !== canvas.height || parent.height !== canvas.height;\r\n if (canvas.clientWidth && canvas.clientHeight && dimsChanged) {\r\n canvas.width = width;\r\n canvas.height = height;\r\n this.setSize(width, height);\r\n }\r\n }\r\n\r\n if (!parent.width || !parent.height) {\r\n return false;\r\n }\r\n\r\n // Render the frame\r\n this._renderFrame();\r\n\r\n this.flushFramebuffer();\r\n\r\n // Copy to target\r\n if (view.clearBeforeCopy) {\r\n context.clearRect(0, 0, parent.width, parent.height);\r\n }\r\n context.drawImage(parent, 0, 0);\r\n\r\n // Restore\r\n if (scene) {\r\n scene.activeCameras = previewCameras;\r\n scene.activeCamera = previewCamera;\r\n }\r\n OnAfterViewRenderObservable.notifyObservers(view);\r\n return true;\r\n };\r\n\r\n AbstractEngine.prototype._renderViews = function () {\r\n if (!this.views || this.views.length === 0) {\r\n return false;\r\n }\r\n\r\n const parent = this.getRenderingCanvas();\r\n\r\n if (!parent) {\r\n return false;\r\n }\r\n\r\n let inputElementView;\r\n for (const view of this.views) {\r\n if (!view.enabled) {\r\n continue;\r\n }\r\n const canvas = view.target;\r\n // Always render the view correspondent to the inputElement for last\r\n if (canvas === this.inputElement) {\r\n inputElementView = view;\r\n continue;\r\n }\r\n\r\n if (!this._renderViewStep(view)) {\r\n return false;\r\n }\r\n }\r\n\r\n if (inputElementView) {\r\n if (!this._renderViewStep(inputElementView)) {\r\n return false;\r\n }\r\n }\r\n\r\n this.activeView = null;\r\n\r\n return true;\r\n };\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"abstractEngine.views.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.views.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Camera } from \"../../Cameras/camera.pure\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene.pure\";\r\nimport { Observable } from \"../../Misc/observable.pure\";\r\nimport { AbstractEngine } from \"../abstractEngine.pure\";\r\n\r\n/**\r\n * Class used to define an additional view for the engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/multiCanvas\r\n */\r\nexport class EngineView {\r\n /**\r\n * A randomly generated unique id\r\n */\r\n readonly id: string;\r\n /** Defines the canvas where to render the view */\r\n target: HTMLCanvasElement;\r\n /**\r\n * Defines an optional camera or array of cameras used to render the view (will use active camera / cameras else)\r\n * Support for array of cameras @since\r\n */\r\n camera?: Camera | Camera[];\r\n /** Indicates if the destination view canvas should be cleared before copying the parent canvas. Can help if the scene clear color has alpha < 1 */\r\n clearBeforeCopy?: boolean;\r\n /** Indicates if the view is enabled (true by default) */\r\n enabled: boolean;\r\n /** Defines a custom function to handle canvas size changes. (the canvas to render into is provided to the callback) */\r\n customResize?: (canvas: HTMLCanvasElement) => void;\r\n}\r\n\r\nlet _Registered = false;\r\n/**\r\n * Register side effects for abstractEngineViews.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterAbstractEngineViews(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const OnBeforeViewRenderObservable = new Observable<EngineView>();\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const OnAfterViewRenderObservable = new Observable<EngineView>();\r\n\r\n Object.defineProperty(AbstractEngine.prototype, \"onBeforeViewRenderObservable\", {\r\n get: function (this: AbstractEngine) {\r\n return OnBeforeViewRenderObservable;\r\n },\r\n });\r\n\r\n Object.defineProperty(AbstractEngine.prototype, \"onAfterViewRenderObservable\", {\r\n get: function (this: AbstractEngine) {\r\n return OnAfterViewRenderObservable;\r\n },\r\n });\r\n\r\n Object.defineProperty(AbstractEngine.prototype, \"inputElement\", {\r\n get: function (this: AbstractEngine) {\r\n return this._inputElement;\r\n },\r\n set: function (this: AbstractEngine, value: HTMLElement) {\r\n if (this._inputElement !== value) {\r\n this._inputElement = value;\r\n this._onEngineViewChanged?.();\r\n }\r\n },\r\n });\r\n\r\n AbstractEngine.prototype.getInputElement = function (): Nullable<HTMLElement> {\r\n return this.inputElement || this.getRenderingCanvas();\r\n };\r\n\r\n AbstractEngine.prototype.registerView = function (\r\n canvas: HTMLCanvasElement,\r\n camera?: Camera | Camera[],\r\n clearBeforeCopy?: boolean,\r\n customResize?: EngineView[\"customResize\"]\r\n ): EngineView {\r\n if (!this.views) {\r\n this.views = [];\r\n }\r\n\r\n for (const view of this.views) {\r\n if (view.target === canvas) {\r\n return view;\r\n }\r\n }\r\n\r\n const masterCanvas = this.getRenderingCanvas();\r\n if (masterCanvas) {\r\n canvas.width = masterCanvas.width;\r\n canvas.height = masterCanvas.height;\r\n }\r\n\r\n const newView = { target: canvas, camera, clearBeforeCopy, enabled: true, id: (Math.random() * 100000).toFixed(), customResize };\r\n this.views.push(newView);\r\n if (customResize) {\r\n customResize(canvas);\r\n }\r\n if (camera && !Array.isArray(camera)) {\r\n camera.onDisposeObservable.add(() => {\r\n this.unRegisterView(canvas);\r\n });\r\n }\r\n\r\n return newView;\r\n };\r\n\r\n AbstractEngine.prototype.unRegisterView = function (canvas: HTMLCanvasElement): AbstractEngine {\r\n if (!this.views || this.views.length === 0) {\r\n return this;\r\n }\r\n\r\n for (const view of this.views) {\r\n if (view.target === canvas) {\r\n const index = this.views.indexOf(view);\r\n\r\n if (index !== -1) {\r\n this.views.splice(index, 1);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n return this;\r\n };\r\n\r\n AbstractEngine.prototype._renderViewStep = function (view: EngineView): boolean {\r\n const canvas = view.target;\r\n const context = canvas.getContext(\"2d\");\r\n if (!context) {\r\n return true;\r\n }\r\n const parent = this.getRenderingCanvas()!;\r\n\r\n OnBeforeViewRenderObservable.notifyObservers(view);\r\n const camera = view.camera;\r\n let previewCamera: Nullable<Camera> = null;\r\n let previewCameras: Nullable<Camera[]> = null;\r\n let scene: Nullable<Scene> = null;\r\n if (camera) {\r\n scene = Array.isArray(camera) ? camera[0].getScene() : camera.getScene();\r\n\r\n previewCamera = scene.activeCamera;\r\n previewCameras = scene.activeCameras;\r\n\r\n if (Array.isArray(camera)) {\r\n scene.activeCameras = camera;\r\n } else {\r\n scene.activeCamera = camera;\r\n scene.activeCameras = null;\r\n }\r\n }\r\n this.activeView = view;\r\n\r\n if (view.customResize) {\r\n view.customResize(canvas);\r\n } else {\r\n // Set sizes\r\n const width = Math.floor(canvas.clientWidth / this._hardwareScalingLevel);\r\n const height = Math.floor(canvas.clientHeight / this._hardwareScalingLevel);\r\n\r\n const dimsChanged = width !== canvas.width || parent.width !== canvas.width || height !== canvas.height || parent.height !== canvas.height;\r\n if (canvas.clientWidth && canvas.clientHeight && dimsChanged) {\r\n canvas.width = width;\r\n canvas.height = height;\r\n this.setSize(width, height);\r\n }\r\n }\r\n\r\n if (!parent.width || !parent.height) {\r\n return false;\r\n }\r\n\r\n // Render the frame\r\n this._renderFrame();\r\n\r\n this.flushFramebuffer();\r\n\r\n // Copy to target\r\n if (view.clearBeforeCopy) {\r\n context.clearRect(0, 0, parent.width, parent.height);\r\n }\r\n context.drawImage(parent, 0, 0);\r\n\r\n // Restore\r\n if (scene) {\r\n scene.activeCameras = previewCameras;\r\n scene.activeCamera = previewCamera;\r\n }\r\n OnAfterViewRenderObservable.notifyObservers(view);\r\n return true;\r\n };\r\n\r\n AbstractEngine.prototype._renderViews = function () {\r\n if (!this.views || this.views.length === 0) {\r\n return false;\r\n }\r\n\r\n const parent = this.getRenderingCanvas();\r\n\r\n if (!parent) {\r\n return false;\r\n }\r\n\r\n let inputElementView;\r\n for (const view of this.views) {\r\n if (!view.enabled) {\r\n continue;\r\n }\r\n const canvas = view.target;\r\n // Always render the view correspondent to the inputElement for last\r\n if (canvas === this.inputElement) {\r\n inputElementView = view;\r\n continue;\r\n }\r\n\r\n if (!this._renderViewStep(view)) {\r\n return false;\r\n }\r\n }\r\n\r\n if (inputElementView) {\r\n if (!this._renderViewStep(inputElementView)) {\r\n return false;\r\n }\r\n }\r\n\r\n this.activeView = null;\r\n\r\n return true;\r\n };\r\n}\r\n"]}
|
|
@@ -35,9 +35,10 @@ declare module "../../Engines/abstractEngine.pure.js" {
|
|
|
35
35
|
* @param canvas defines the canvas to register
|
|
36
36
|
* @param camera defines an optional camera or array of cameras to use with this canvas (it will overwrite the scene.activeCamera / scene.activeCameras for this view). Support for array of cameras @since
|
|
37
37
|
* @param clearBeforeCopy Indicates if the destination view canvas should be cleared before copying the parent canvas. Can help if the scene clear color has alpha \< 1
|
|
38
|
+
* @param customResize defines the canvas custom resize handle
|
|
38
39
|
* @returns the associated view
|
|
39
40
|
*/
|
|
40
|
-
registerView(canvas: HTMLCanvasElement, camera?: Camera | Camera[], clearBeforeCopy?: boolean): EngineView;
|
|
41
|
+
registerView(canvas: HTMLCanvasElement, camera?: Camera | Camera[], clearBeforeCopy?: boolean, customResize?: EngineView["customResize"]): EngineView;
|
|
41
42
|
/**
|
|
42
43
|
* Remove a registered child canvas
|
|
43
44
|
* @param canvas defines the canvas to remove
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstractEngine.views.types.js","sourceRoot":"","sources":["../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.views.types.ts"],"names":[],"mappings":"","sourcesContent":["import { type Camera } from \"../../Cameras/camera\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observable } from \"../../Misc/observable\";\r\nimport { type EngineView } from \"./abstractEngine.views.pure\";\r\ndeclare module \"../../Engines/abstractEngine.pure\" {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n export interface AbstractEngine {\r\n /** @internal */\r\n _inputElement: Nullable<HTMLElement>;\r\n\r\n /**\r\n * Gets or sets the HTML element to use for attaching events\r\n */\r\n inputElement: Nullable<HTMLElement>;\r\n\r\n /**\r\n * Observable to handle when a change to inputElement occurs\r\n * @internal\r\n */\r\n _onEngineViewChanged?: () => void;\r\n\r\n /**\r\n * Will be triggered before the view renders\r\n */\r\n readonly onBeforeViewRenderObservable: Observable<EngineView>;\r\n /**\r\n * Will be triggered after the view rendered\r\n */\r\n readonly onAfterViewRenderObservable: Observable<EngineView>;\r\n\r\n /**\r\n * Gets the current engine view\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/multiCanvas\r\n */\r\n activeView: Nullable<EngineView>;\r\n\r\n /** Gets or sets the list of views */\r\n views: EngineView[];\r\n\r\n /**\r\n * Register a new child canvas\r\n * @param canvas defines the canvas to register\r\n * @param camera defines an optional camera or array of cameras to use with this canvas (it will overwrite the scene.activeCamera / scene.activeCameras for this view). Support for array of cameras @since\r\n * @param clearBeforeCopy Indicates if the destination view canvas should be cleared before copying the parent canvas. Can help if the scene clear color has alpha \\< 1\r\n * @returns the associated view\r\n */\r\n registerView(canvas: HTMLCanvasElement, camera?: Camera | Camera[], clearBeforeCopy?: boolean): EngineView;\r\n\r\n /**\r\n * Remove a registered child canvas\r\n * @param canvas defines the canvas to remove\r\n * @returns the current engine\r\n */\r\n unRegisterView(canvas: HTMLCanvasElement): AbstractEngine;\r\n\r\n /**\r\n * @internal\r\n */\r\n _renderViewStep(view: EngineView): boolean;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"abstractEngine.views.types.js","sourceRoot":"","sources":["../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.views.types.ts"],"names":[],"mappings":"","sourcesContent":["import { type Camera } from \"../../Cameras/camera\";\r\nimport { type Nullable } from \"../../types\";\r\nimport { type Observable } from \"../../Misc/observable\";\r\nimport { type EngineView } from \"./abstractEngine.views.pure\";\r\ndeclare module \"../../Engines/abstractEngine.pure\" {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n export interface AbstractEngine {\r\n /** @internal */\r\n _inputElement: Nullable<HTMLElement>;\r\n\r\n /**\r\n * Gets or sets the HTML element to use for attaching events\r\n */\r\n inputElement: Nullable<HTMLElement>;\r\n\r\n /**\r\n * Observable to handle when a change to inputElement occurs\r\n * @internal\r\n */\r\n _onEngineViewChanged?: () => void;\r\n\r\n /**\r\n * Will be triggered before the view renders\r\n */\r\n readonly onBeforeViewRenderObservable: Observable<EngineView>;\r\n /**\r\n * Will be triggered after the view rendered\r\n */\r\n readonly onAfterViewRenderObservable: Observable<EngineView>;\r\n\r\n /**\r\n * Gets the current engine view\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/multiCanvas\r\n */\r\n activeView: Nullable<EngineView>;\r\n\r\n /** Gets or sets the list of views */\r\n views: EngineView[];\r\n\r\n /**\r\n * Register a new child canvas\r\n * @param canvas defines the canvas to register\r\n * @param camera defines an optional camera or array of cameras to use with this canvas (it will overwrite the scene.activeCamera / scene.activeCameras for this view). Support for array of cameras @since\r\n * @param clearBeforeCopy Indicates if the destination view canvas should be cleared before copying the parent canvas. Can help if the scene clear color has alpha \\< 1\r\n * @param customResize defines the canvas custom resize handle\r\n * @returns the associated view\r\n */\r\n registerView(canvas: HTMLCanvasElement, camera?: Camera | Camera[], clearBeforeCopy?: boolean, customResize?: EngineView[\"customResize\"]): EngineView;\r\n\r\n /**\r\n * Remove a registered child canvas\r\n * @param canvas defines the canvas to remove\r\n * @returns the current engine\r\n */\r\n unRegisterView(canvas: HTMLCanvasElement): AbstractEngine;\r\n\r\n /**\r\n * @internal\r\n */\r\n _renderViewStep(view: EngineView): boolean;\r\n }\r\n}\r\n"]}
|
|
@@ -194,6 +194,13 @@ export class AbstractEngine {
|
|
|
194
194
|
_rebuildRenderTargetWrappers() {
|
|
195
195
|
const currentState = this._renderTargetWrapperCache.slice(); // Do a copy because the rebuild will add proxies
|
|
196
196
|
for (const renderTargetWrapper of currentState) {
|
|
197
|
+
// Wrapped textures (source === External) are host-owned; their format is opaque to Babylon, so we can't
|
|
198
|
+
// rebuild them. The host re-supplies a fresh handle via updateWrappedWebGLTexture /
|
|
199
|
+
// updateWrappedNativeTexture / updateWrappedWebGPUTexture from its onContextRestoredObservable handler.
|
|
200
|
+
// Scan all attachments for the multi-RT case (rtWrapper.texture only returns _textures[0]).
|
|
201
|
+
if (renderTargetWrapper.textures?.some((t) => t.source === 15 /* InternalTextureSource.External */)) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
197
204
|
renderTargetWrapper._rebuild();
|
|
198
205
|
}
|
|
199
206
|
}
|
|
@@ -815,13 +822,13 @@ export class AbstractEngine {
|
|
|
815
822
|
*/
|
|
816
823
|
// Not mixed with Version for tooling purpose.
|
|
817
824
|
static get NpmPackage() {
|
|
818
|
-
return "babylonjs@9.
|
|
825
|
+
return "babylonjs@9.9.1";
|
|
819
826
|
}
|
|
820
827
|
/**
|
|
821
828
|
* Returns the current version of the framework
|
|
822
829
|
*/
|
|
823
830
|
static get Version() {
|
|
824
|
-
return "9.
|
|
831
|
+
return "9.9.1";
|
|
825
832
|
}
|
|
826
833
|
/**
|
|
827
834
|
* Gets the HTML canvas attached with the current webGL context
|
|
@@ -1139,8 +1146,6 @@ export class AbstractEngine {
|
|
|
1139
1146
|
// Detect if we are running on a faulty buggy desktop OS.
|
|
1140
1147
|
this._badDesktopOS = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
1141
1148
|
}
|
|
1142
|
-
// Save this off for use in resize().
|
|
1143
|
-
this.adaptToDeviceRatio = adaptToDeviceRatio ?? false;
|
|
1144
1149
|
options.antialias = antialias ?? options.antialias;
|
|
1145
1150
|
options.deterministicLockstep = options.deterministicLockstep ?? false;
|
|
1146
1151
|
options.lockstepMaxSteps = options.lockstepMaxSteps ?? 4;
|
|
@@ -1156,6 +1161,8 @@ export class AbstractEngine {
|
|
|
1156
1161
|
const limitDeviceRatio = options.limitDeviceRatio || devicePixelRatio;
|
|
1157
1162
|
// Viewport
|
|
1158
1163
|
adaptToDeviceRatio = adaptToDeviceRatio || options.adaptToDeviceRatio || false;
|
|
1164
|
+
// Save this off for use in resize().
|
|
1165
|
+
this.adaptToDeviceRatio = adaptToDeviceRatio;
|
|
1159
1166
|
this._hardwareScalingLevel = adaptToDeviceRatio ? 1.0 / Math.min(limitDeviceRatio, devicePixelRatio) : 1.0;
|
|
1160
1167
|
this._lastDevicePixelRatio = devicePixelRatio;
|
|
1161
1168
|
this._creationOptions = options;
|