Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Revert "Revert "PointerManager support multi pointer event"" #1129

Merged
merged 1 commit into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions packages/core/src/Script.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Camera } from "./Camera";
import { ignoreClone } from "./clone/CloneManager";
import { Component } from "./Component";
import { Pointer } from "./input";
import { ColliderShape } from "./physics";

/**
Expand Down Expand Up @@ -117,34 +118,40 @@ export class Script extends Component {

/**
* Called when the pointer is down while over the ColliderShape.
* @param pointer - The pointer that triggered
*/
onPointerDown(): void {}
onPointerDown(pointer: Pointer): void {}

/**
* Called when the pointer is up while over the ColliderShape.
* @param pointer - The pointer that triggered
*/
onPointerUp(): void {}
onPointerUp(pointer: Pointer): void {}

/**
* Called when the pointer is down and up with the same collider.
* @param pointer - The pointer that triggered
*/
onPointerClick(): void {}
onPointerClick(pointer: Pointer): void {}

/**
* Called when the pointer is enters the ColliderShape.
* @param pointer - The pointer that triggered
*/
onPointerEnter(): void {}
onPointerEnter(pointer: Pointer): void {}

/**
* Called when the pointer is no longer over the ColliderShape.
* @param pointer - The pointer that triggered
*/
onPointerExit(): void {}
onPointerExit(pointer: Pointer): void {}

/**
* Called when the pointer is down while over the ColliderShape and is still holding down.
* @param pointer - The pointer that triggered
* @remarks onPointerDrag is called every frame while the pointer is down.
*/
onPointerDrag(): void {}
onPointerDrag(pointer: Pointer): void {}

/**
* Called when be disabled.
Expand Down
28 changes: 5 additions & 23 deletions packages/core/src/input/InputManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { KeyboardManager } from "./keyboard/KeyboardManager";
import { Keys } from "./enums/Keys";
import { Pointer } from "./pointer/Pointer";
import { PointerManager } from "./pointer/PointerManager";
import { PointerButton } from "./enums/PointerButton";
import { PointerButton, _pointerBin2DecMap } from "./enums/PointerButton";
import { WheelManager } from "./wheel/WheelManager";
import { Vector2, Vector3 } from "@oasis-engine/math";

Expand All @@ -19,7 +19,7 @@ export class InputManager {
private _keyboardManager: KeyboardManager;

/**
* Pointer List.
* Pointer list.
*/
get pointers(): Readonly<Pointer[] | null> {
return this._initialized ? this._pointerManager._pointers : null;
Expand All @@ -44,24 +44,6 @@ export class InputManager {
return this._initialized ? this._wheelManager._delta : null;
}

/**
* Get the change of the pointer.
* @returns Change value
*/
get pointerMovingDelta(): Readonly<Vector2 | null> {
return this._initialized ? this._pointerManager._movingDelta : null;
}

/**
* Get the position of the pointer.
* @returns The position of the pointer
*/
get pointerPosition(): Readonly<Vector2> {
return this._initialized && this._pointerManager._pointers.length > 0
? this._pointerManager._currentPosition
: null;
}

/**
* Whether the key is being held down, if there is no parameter, return whether any key is being held down.
* @param key - The keys of the keyboard
Expand Down Expand Up @@ -123,7 +105,7 @@ export class InputManager {
if (pointerButton === undefined) {
return this._pointerManager._buttons !== 0;
} else {
return (this._pointerManager._buttons & PointerManager.Buttons[pointerButton]) !== 0;
return (this._pointerManager._buttons & pointerButton) !== 0;
}
} else {
return false;
Expand All @@ -140,7 +122,7 @@ export class InputManager {
if (pointerButton === undefined) {
return this._pointerManager._downList.length > 0;
} else {
return this._pointerManager._downMap[pointerButton] === this._curFrameCount;
return this._pointerManager._downMap[_pointerBin2DecMap[pointerButton]] === this._curFrameCount;
}
} else {
return false;
Expand All @@ -157,7 +139,7 @@ export class InputManager {
if (pointerButton === undefined) {
return this._pointerManager._upList.length > 0;
} else {
return this._pointerManager._upMap[pointerButton] === this._curFrameCount;
return this._pointerManager._upMap[_pointerBin2DecMap[pointerButton]] === this._curFrameCount;
}
} else {
return false;
Expand Down
75 changes: 62 additions & 13 deletions packages/core/src/input/enums/PointerButton.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,78 @@
/**
* Defines values that specify the buttons on a pointer device.
* Refer to the W3C standards.(https://www.w3.org/TR/uievents/#dom-mouseevent-button)
* Refer to the W3C standards:
* (https://www.w3.org/TR/uievents/#dom-mouseevent-button)
* (https://www.w3.org/TR/uievents/#dom-mouseevent-buttons)
* Refer to Microsoft's documentation.(https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.mousebutton?view=windowsdesktop-6.0)
*/
export enum PointerButton {
/** No button. */
None = 0x0,
/** Indicate the primary pointer of the device (in general, the left button or the only button on single-button devices, used to activate a user interface control or select text) or the un-initialized value. */
Primary = 0,
/** Indicate the auxiliary pointer (in general, the middle button, often combined with a mouse wheel). */
Auxiliary = 1,
Primary = 0x1,
/** Indicate the secondary pointer (in general, the right button, often used to display a context menu). */
Secondary = 2,
Secondary = 0x2,
/** Indicate the auxiliary pointer (in general, the middle button, often combined with a mouse wheel). */
Auxiliary = 0x4,
/** Indicate the X1 (back) pointer. */
XButton1 = 3,
XButton1 = 0x8,
/** Indicate the X2 (forward) pointer. */
XButton2 = 4,
XButton2 = 0x10,
/** Indicate the X3 pointer. */
XButton3 = 5,
XButton3 = 0x20,
/** Indicate the X4 pointer. */
XButton4 = 6,
XButton4 = 0x40,
/** Indicate the X5 pointer. */
XButton5 = 7,
XButton5 = 0x80,
/** Indicate the X6 pointer. */
XButton6 = 8,
XButton6 = 0x100,
/** Indicate the X7 pointer. */
XButton7 = 9,
XButton7 = 0x200,
/** Indicate the X8 pointer. */
XButton8 = 10
XButton8 = 0x400
}

/**
* @internal
*/
export const _pointerDec2BinMap = [
PointerButton.Primary,
PointerButton.Auxiliary,
PointerButton.Secondary,
PointerButton.XButton1,
PointerButton.XButton2,
PointerButton.XButton3,
PointerButton.XButton4,
PointerButton.XButton5,
PointerButton.XButton6,
PointerButton.XButton7,
PointerButton.XButton8
];

/**
* @internal
*/
export const _pointerBin2DecMap: Record<number, number> = {
/** Primary */
0x1: 0,
/** Secondary */
0x2: 2,
/** Auxiliary */
0x4: 1,
/** XButton1 */
0x8: 3,
/** XButton2 */
0x10: 4,
/** XButton3 */
0x20: 5,
/** XButton4 */
0x40: 6,
/** XButton5 */
0x80: 7,
/** XButton6 */
0x100: 8,
/** XButton7 */
0x200: 9,
/** XButton8 */
0x400: 10
};
2 changes: 2 additions & 0 deletions packages/core/src/input/enums/PointerPhase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export enum PointerPhase {
Down,
/** A pointer moved on the screen. */
Move,
/** A Pointer pressed on the screen but hasn't moved. */
Stationary,
/** A pointer was lifted from the screen. */
Up,
/** The system cancelled tracking for the pointer. */
Expand Down
75 changes: 74 additions & 1 deletion packages/core/src/input/pointer/Pointer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Vector2 } from "@oasis-engine/math";
import { Entity } from "../../Entity";
import { PointerButton } from "../enums/PointerButton";
import { PointerPhase } from "../enums/PointerPhase";

/**
Expand All @@ -12,12 +14,83 @@ export class Pointer {
readonly id: number;
/** The phase of pointer. */
phase: PointerPhase = PointerPhase.Leave;
/** The button that triggers the pointer event. */
button: PointerButton;
/** The currently pressed buttons for this pointer. */
pressedButtons: PointerButton;
/** The position of the pointer in screen space pixel coordinates. */
position: Vector2 = new Vector2();

/** The change of the pointer. */
deltaPosition: Vector2 = new Vector2();
/** @internal */
_events: PointerEvent[] = [];
/** @internal */
_uniqueID: number;

private _currentPressedEntity: Entity;
private _currentEnteredEntity: Entity;

/** @internal */
_firePointerExitAndEnter(rayCastEntity: Entity): void {
if (this._currentEnteredEntity !== rayCastEntity) {
if (this._currentEnteredEntity) {
const scripts = this._currentEnteredEntity._scripts;
for (let i = scripts.length - 1; i >= 0; i--) {
const script = scripts.get(i);
script._waitHandlingInValid || script.onPointerExit(this);
}
}
if (rayCastEntity) {
const scripts = rayCastEntity._scripts;
for (let i = scripts.length - 1; i >= 0; i--) {
const script = scripts.get(i);
script._waitHandlingInValid || script.onPointerEnter(this);
}
}
this._currentEnteredEntity = rayCastEntity;
}
}

/** @internal */
_firePointerDown(rayCastEntity: Entity): void {
if (rayCastEntity) {
const scripts = rayCastEntity._scripts;
for (let i = scripts.length - 1; i >= 0; i--) {
const script = scripts.get(i);
script._waitHandlingInValid || script.onPointerDown(this);
}
}
this._currentPressedEntity = rayCastEntity;
}

/** @internal */
_firePointerDrag(): void {
if (this._currentPressedEntity) {
const scripts = this._currentPressedEntity._scripts;
for (let i = scripts.length - 1; i >= 0; i--) {
const script = scripts.get(i);
script._waitHandlingInValid || script.onPointerDrag(this);
}
}
}

/** @internal */
_firePointerUpAndClick(rayCastEntity: Entity): void {
const { _currentPressedEntity: pressedEntity } = this;
if (pressedEntity) {
const sameTarget = pressedEntity === rayCastEntity;
const scripts = pressedEntity._scripts;
for (let i = scripts.length - 1; i >= 0; i--) {
const script = scripts.get(i);
if (!script._waitHandlingInValid) {
sameTarget && script.onPointerClick(this);
script.onPointerUp(this);
}
}
this._currentPressedEntity = null;
}
}

/**
* @internal
*/
Expand Down
Loading