ソースを参照

PointerTracker: introduce the adjusted space

customisations
alemart 9ヶ月前
コミット
9bbfb73a5a

+ 26
- 3
docs/api/pointer-tracker.md ファイルの表示

@@ -8,9 +8,14 @@ A [tracker](tracker.md) of [pointers](trackable-pointer.md). It consumes data fr
8 8
 
9 9
 ### AR.Tracker.Pointer
10 10
 
11
-`AR.Tracker.Pointer(): PointerTracker`
11
+`AR.Tracker.Pointer(options: object): PointerTracker`
12 12
 
13
-Create a new `PointerTracker`.
13
+Create a new `PointerTracker` with the specified `options`.
14
+
15
+**Arguments**
16
+
17
+* `options: object, optional`. An object with the following keys (all are optional):
18
+    * `space: string`. The [space](#space) in which pointers will be located. Defaults to `"normalized"`.
14 19
 
15 20
 **Returns**
16 21
 
@@ -19,7 +24,11 @@ A new `PointerTracker`.
19 24
 **Example**
20 25
 
21 26
 ```js
27
+// Use default settings
22 28
 const pointerTracker = AR.Tracker.Pointer();
29
+
30
+// Track pointers in adjusted space
31
+const pointerTracker = AR.Tracker.Pointer({ space: 'adjusted' });
23 32
 ```
24 33
 
25 34
 ## Properties
@@ -28,4 +37,18 @@ const pointerTracker = AR.Tracker.Pointer();
28 37
 
29 38
 `tracker.type: string, read-only`
30 39
 
31
-The string `"pointer-tracker"`.
40
+The string `"pointer-tracker"`.
41
+
42
+### space
43
+
44
+`tracker.space: string, read-only`
45
+
46
+The space in which pointers are located. You may set it when instantiating the tracker. Possible values: `"normalized"` or `"adjusted"`.
47
+
48
+- In `"normalized"` space, pointers are located in [-1,1]x[-1,1]. The origin of the space is at the center of the [viewport](viewport.md). The x-axis points to the right and the y-axis points up. This is the default space.
49
+
50
+- The `"adjusted"` space is similar to the normalized space, except that it is scaled so that it matches the [aspect ratio](viewport.md#aspectratio) of the viewport.
51
+
52
+    Pointers in adjusted space are contained in normalized space, but unless the viewport is a square, one of their coordinates, x or y, will no longer range from -1 to +1. It will range from *-s* to *+s*, where *s = min(a, 1/a)*. In this expression, *a* is the aspect ratio of the viewport and *s* is less than or equal to 1.
53
+
54
+    Selecting the adjusted space is useful for making sure that pointer speeds are equivalent in both axes and for preserving movement curves. Speeds are not equivalent and movement curves are not preserved by default because the normalized space is a square, whereas the viewport is a rectangle.

+ 4
- 4
docs/api/trackable-pointer.md ファイルの表示

@@ -4,7 +4,7 @@ A [trackable](trackable.md) that represents a pointer tracked by a [PointerTrack
4 4
 
5 5
 A pointer is an abstraction that represents an instance of user input that targets one or more coordinates on a screen. For example, each point of contact between fingers and a multitouch screen generate a pointer. Devices such as a mouse and a pen/stylus also generate pointers.
6 6
 
7
-Pointers are positioned in the [viewport](viewport.md). Their positions are given in normalized units, which range from -1 to +1. The center of the viewport is at (0,0). The top right corner is at (1,1). The bottom left corner is at (-1,-1).
7
+Pointers are located in the [viewport](viewport.md). Their positions are given in [space units](pointer-tracker.md#space). By default, space units are normalized units, which range from -1 to +1. In normalized space, the center of the viewport is at (0,0). The top right corner is at (1,1). The bottom left corner is at (-1,-1).
8 8
 
9 9
 *Since:* 0.4.0
10 10
 
@@ -32,7 +32,7 @@ The phase of the pointer. It's one of the following strings:
32 32
 
33 33
 `pointer.position: Vector2, read-only`
34 34
 
35
-The current position of the pointer, given in normalized units. See also: [Viewer.raycast](viewer.md#raycast), [Viewport.convertToPixels](viewport.md#converttopixels).
35
+The current position of the pointer, given in space units. See also: [PointerTracker.space](pointer-tracker.md#space), [Viewer.raycast](viewer.md#raycast), [Viewport.convertToPixels](viewport.md#converttopixels).
36 36
 
37 37
 ### initialPosition
38 38
 
@@ -50,7 +50,7 @@ The difference between the position of the pointer in this and in the previous f
50 50
 
51 51
 `pointer.velocity: Vector2, read-only`
52 52
 
53
-The current velocity of the pointer, given in normalized units per second. You can get the current speed of motion by calculating the [magnitude](vector2.md#length) of this vector.
53
+The current velocity of the pointer, given in space units per second. You can get the current speed of motion by calculating the [magnitude](vector2.md#length) of this vector.
54 54
 
55 55
 ### elapsedTime
56 56
 
@@ -62,7 +62,7 @@ The elapsed time, in seconds, since the tracking of this pointer began.
62 62
 
63 63
 `pointer.totalDistance: number, read-only`
64 64
 
65
-How much this pointer has moved, in normalized units, since its tracking began. You can get the average speed of motion by calculating the ratio `totalDistance / elapsedTime`.
65
+How much this pointer has moved, in space units, since its tracking began. You can get the average speed of motion by calculating the ratio `totalDistance / elapsedTime`.
66 66
 
67 67
 ### isPrimary
68 68
 

+ 88
- 3
src/trackers/pointer-tracker/pointer-tracker.ts ファイルの表示

@@ -27,7 +27,7 @@ import { TrackablePointer, TrackablePointerPhase } from './trackable-pointer';
27 27
 import { PointerSource } from '../../sources/pointer-source';
28 28
 import { Vector2 } from '../../geometry/vector2';
29 29
 import { Utils, Nullable } from '../../utils/utils';
30
-import { IllegalOperationError } from '../../utils/errors';
30
+import { IllegalOperationError, IllegalArgumentError } from '../../utils/errors';
31 31
 import { Session } from '../../core/session';
32 32
 import { Viewport } from '../../core/viewport';
33 33
 
@@ -52,6 +52,38 @@ export interface PointerTrackerOutput extends TrackerOutput
52 52
     readonly exports: PointerTrackerResult;
53 53
 }
54 54
 
55
+/**
56
+ * The space in which pointers are located.
57
+ *
58
+ * - In "normalized" space, pointers are located in [-1,1]x[-1,1]. The origin
59
+ *   of the space is at the center of the viewport. The x-axis points to the
60
+ *   right and the y-axis points up. This is the default space.
61
+ *
62
+ * - The "adjusted" space is similar to the normalized space, except that it is
63
+ *   scaled so that it matches the aspect ratio of the viewport.
64
+ *
65
+ *   Pointers in adjusted space are contained in normalized space, but unless
66
+ *   the viewport is a square, one of their coordinates, x or y, will no longer
67
+ *   range from -1 to +1. It will range from -s to +s, where s = min(a, 1/a).
68
+ *   In this expression, a is the aspect ratio of the viewport and s is less
69
+ *   than or equal to 1.
70
+ *
71
+ *   Selecting the adjusted space is useful for making sure that pointer speeds
72
+ *   are equivalent in both axes and for preserving movement curves. Speeds are
73
+ *   not equivalent and movement curves are not preserved by default because
74
+ *   the normalized space is a square, whereas the viewport is a rectangle.
75
+ */
76
+export type PointerSpace = 'normalized' | 'adjusted'; // | 'viewport';
77
+
78
+/**
79
+ * Options for instantiating a PointerTracker
80
+ */
81
+export interface PointerTrackerOptions
82
+{
83
+    /** the space in which pointers will be located */
84
+    space?: PointerSpace;
85
+}
86
+
55 87
 /** Convert event type to trackable pointer phase */
56 88
 const EVENTTYPE2PHASE: Record<string, TrackablePointerPhase> = {
57 89
     'pointerdown': 'began',
@@ -62,6 +94,11 @@ const EVENTTYPE2PHASE: Record<string, TrackablePointerPhase> = {
62 94
     'pointerenter': 'began',
63 95
 };
64 96
 
97
+/** Default options for instantiating a PointerTracker */
98
+const DEFAULT_OPTIONS: Readonly<Required<PointerTrackerOptions>> = {
99
+    space: 'normalized'
100
+};
101
+
65 102
 
66 103
 
67 104
 
@@ -76,6 +113,9 @@ export class PointerTracker implements Tracker
76 113
     /** the viewport */
77 114
     private _viewport: Nullable<Viewport>;
78 115
 
116
+    /** pointer space */
117
+    private _space: PointerSpace;
118
+
79 119
     /** active pointers */
80 120
     private _activePointers: Map<number, TrackablePointer>;
81 121
 
@@ -99,13 +139,20 @@ export class PointerTracker implements Tracker
99 139
 
100 140
 
101 141
 
142
+
143
+
144
+
102 145
     /**
103 146
      * Constructor
147
+     * @param options
104 148
      */
105
-    constructor()
149
+    constructor(options: PointerTrackerOptions)
106 150
     {
151
+        const settings = this._buildSettings(options);
152
+
107 153
         this._source = null;
108 154
         this._viewport = null;
155
+        this._space = settings.space;
109 156
         this._activePointers = new Map();
110 157
         this._newPointers = new Map();
111 158
         this._idMap = new Map();
@@ -117,6 +164,21 @@ export class PointerTracker implements Tracker
117 164
     }
118 165
 
119 166
     /**
167
+     * Build a full and validated options object
168
+     * @param options
169
+     * @returns validated options with defaults
170
+     */
171
+    private _buildSettings(options: PointerTrackerOptions): Required<PointerTrackerOptions>
172
+    {
173
+        const settings: Required<PointerTrackerOptions> = Object.assign({}, DEFAULT_OPTIONS, options);
174
+
175
+        if(settings.space != 'normalized' && settings.space != 'adjusted')
176
+            throw new IllegalArgumentError(`Invalid pointer space: "${settings.space}"`);
177
+
178
+        return settings;
179
+    }
180
+
181
+    /**
120 182
      * The type of the tracker
121 183
      */
122 184
     get type(): string
@@ -283,13 +345,27 @@ export class PointerTracker implements Tracker
283 345
                     continue;
284 346
             }
285 347
 
286
-            // determine the current position
348
+            // determine the current position in normalized space
287 349
             const absX = event.pageX - (rect.left + window.scrollX);
288 350
             const absY = event.pageY - (rect.top + window.scrollY);
289 351
             const relX = 2 * absX / rect.width - 1; // convert to [-1,1]
290 352
             const relY = -(2 * absY / rect.height - 1); // flip Y axis
291 353
             const position = new Vector2(relX, relY);
292 354
 
355
+            // scale the normalized space so that it matches the aspect ratio of the viewport
356
+            if(this._space == 'adjusted') {
357
+                const a = this._viewport!.aspectRatio;
358
+
359
+                if(a >= 1) {
360
+                    // landscape
361
+                    position._set(relX, relY / a);
362
+                }
363
+                else {
364
+                    // portrait
365
+                    position._set(relX * a, relY);
366
+                }
367
+            }
368
+
293 369
             // determine the position delta
294 370
             const deltaPosition = !previous ? Vector2.ZERO :
295 371
                                   position._clone()._subtract(previous.position);
@@ -360,6 +436,15 @@ export class PointerTracker implements Tracker
360 436
     }
361 437
 
362 438
     /**
439
+     * The space in which pointers are located.
440
+     * You may set it when instantiating the tracker.
441
+     */
442
+    get space(): PointerSpace
443
+    {
444
+        return this._space;
445
+    }
446
+
447
+    /**
363 448
      * Generate tracker output
364 449
      * @returns a new PointerTrackerOutput object
365 450
      */

+ 3
- 3
src/trackers/pointer-tracker/trackable-pointer.ts ファイルの表示

@@ -44,7 +44,7 @@ export interface TrackablePointer extends Trackable
44 44
     /** the phase of the pointer */
45 45
     readonly phase: TrackablePointerPhase;
46 46
 
47
-    /** current position in normalized units [-1,1]x[-1,1] */
47
+    /** current position, given in space units */
48 48
     readonly position: Vector2;
49 49
 
50 50
     /** the difference between the position of the pointer in this and in the previous frame */
@@ -53,13 +53,13 @@ export interface TrackablePointer extends Trackable
53 53
     /** the position of the pointer when its tracking began */
54 54
     readonly initialPosition: Vector2;
55 55
 
56
-    /** current velocity, given in normalized units per second */
56
+    /** current velocity, given in space units per second */
57 57
     readonly velocity: Vector2;
58 58
 
59 59
     /** elapsed time, in seconds, since the tracking of this pointer began */
60 60
     readonly elapsedTime: number;
61 61
 
62
-    /** how much this pointer has moved, in normalized units, since its tracking began */
62
+    /** how much this pointer has moved, in space units, since its tracking began */
63 63
     readonly totalDistance: number;
64 64
 
65 65
     /** whether or not this is the primary pointer for this type */

+ 4
- 3
src/trackers/tracker-factory.ts ファイルの表示

@@ -21,7 +21,7 @@
21 21
  */
22 22
 
23 23
 import { ImageTracker, ImageTrackerOptions } from './image-tracker/image-tracker';
24
-import { PointerTracker } from './pointer-tracker/pointer-tracker';
24
+import { PointerTracker, PointerTrackerOptions } from './pointer-tracker/pointer-tracker';
25 25
 
26 26
 /**
27 27
  * Tracker factory
@@ -48,9 +48,10 @@ export class TrackerFactory
48 48
 
49 49
     /**
50 50
      * Create a Pointer Tracker
51
+     * @param options
51 52
      */
52
-    static Pointer(): PointerTracker
53
+    static Pointer(options: PointerTrackerOptions = {}): PointerTracker
53 54
     {
54
-        return new PointerTracker();
55
+        return new PointerTracker(options);
55 56
     }
56 57
 }

読み込み中…
キャンセル
保存