Jelajahi Sumber

Merge branch 'engine2d' of https://github.com/Nockawa/Babylon.js.git

nockawa 9 tahun lalu
induk
melakukan
4361fc2480

+ 19 - 4
src/Canvas2d/babylon.canvas2d.ts

@@ -192,7 +192,10 @@
             this.scene.onPrePointerObservable.add((e, s) => this._handlePointerEventForInteraction(e, s));
         }
 
-        public setPointerCapture(pointerId: number, primitive: Prim2DBase): boolean {
+        /**
+         * Internal method, you should use the Prim2DBase version instead
+         */
+        public _setPointerCapture(pointerId: number, primitive: Prim2DBase): boolean {
             if (this.isPointerCaptured(pointerId)) {
                 return false;
             }
@@ -211,7 +214,10 @@
             return true;
         }
 
-        public releasePointerCapture(pointerId: number, primitive: Prim2DBase): boolean {
+        /**
+         * Internal method, you should use the Prim2DBase version instead
+         */
+        public _releasePointerCapture(pointerId: number, primitive: Prim2DBase): boolean {
             if (this._capturedPointers.get(pointerId.toString()) !== primitive) {
                 return false;
             }
@@ -229,7 +235,12 @@
             return true;
         }
 
-        public isPointerCaptured(pointerId: number) {
+        /**
+         * Determine if the given pointer is captured or not
+         * @param pointerId the Id of the pointer
+         * @return true if it's captured, false otherwise
+         */
+        public isPointerCaptured(pointerId: number): boolean {
             return this._capturedPointers.contains(pointerId.toString());
         }
 
@@ -388,7 +399,7 @@
             }
         }
 
-        private _notifDebugMode = true;
+        private _notifDebugMode = false;
         private _debugExecObserver(prim: Prim2DBase, mask: number) {
             if (!this._notifDebugMode) {
                 return;
@@ -616,6 +627,10 @@
             this._background.levelVisible = true;
         }
 
+        /**
+         * Enable/Disable interaction for this Canvas
+         * When enabled the Prim2DBase.pointerEventObservable property will notified when appropriate events occur
+         */
         public get interactionEnabled(): boolean {
             return this._interactionEnabled;
         }

+ 1 - 1
src/Canvas2d/babylon.group2d.ts

@@ -272,7 +272,7 @@
 
                         // We need to check if prepare is needed because even if the primitive is in the dirtyList, its parent primitive may also have been modified, then prepared, then recurse on its children primitives (this one for instance) if the changes where impacting them.
                         // For instance: a Rect's position change, the position of its children primitives will also change so a prepare will be call on them. If a child was in the dirtyList we will avoid a second prepare by making this check.
-                        if (!p.isDisposed && p.needPrepare()) {
+                        if (!p.isDisposed && p._needPrepare()) {
                             p._prepareRender(context);
                         }
                     });

+ 168 - 9
src/Canvas2d/babylon.prim2dBase.ts

@@ -4,6 +4,10 @@
         forceRefreshPrimitive: boolean;
     }
 
+    /**
+     * This class store information for the pointerEventObservable Observable.
+     * The Observable is divided into many sub events (using the Mask feature of the Observable pattern): PointerOver, PointerEnter, PointerDown, PointerMouseWheel, PointerMove, PointerUp, PointerDown, PointerLeave, PointerGotCapture and PointerLostCapture.
+     */
     export class PrimitivePointerInfo {
         private static _pointerOver        = 0x0001;
         private static _pointerEnter       = 0x0002;
@@ -134,18 +138,52 @@
          */
         cancelBubble: boolean;
 
+        /**
+         * True if the Control keyboard key is down
+         */
         ctrlKey: boolean;
+
+        /**
+         * true if the Shift keyboard key is down
+         */
         shiftKey: boolean;
+
+        /**
+         * true if the Alt keyboard key is down
+         */
         altKey: boolean;
+
+        /**
+         * true if the Meta keyboard key is down
+         */
         metaKey: boolean;
+
+        /**
+         * For button, buttons, refer to https://www.w3.org/TR/pointerevents/#button-states
+         */
         button: number;
+        /**
+         * For button, buttons, refer to https://www.w3.org/TR/pointerevents/#button-states
+         */
         buttons: number;
+
+        /**
+         * The amount of mouse wheel rolled
+         */
         mouseWheelDelta: number;
+
+        /**
+         * Id of the Pointer involved in the event
+         */
         pointerId: number;
         width: number;
         height: number;
         presssure: number;
         tilt: Vector2;
+
+        /**
+         * true if the involved pointer is captured for a particular primitive, false otherwise.
+         */
         isCaptured: boolean;
 
         constructor() {
@@ -175,12 +213,18 @@
         }
     }
 
+    /**
+     * Stores information about a Primitive that was intersected
+     */
     export class PrimitiveIntersectedInfo {
         constructor(public prim: Prim2DBase, public intersectionLocation: Vector2) {
             
         }
     }
 
+    /**
+     * Main class used for the Primitive Intersection API
+     */
     export class IntersectInfo2D {
         constructor() {
             this.findFirstOnly = false;
@@ -189,8 +233,20 @@
         }
 
         // Input settings, to setup before calling an intersection related method
+
+        /**
+         * Set the pick position, relative to the primitive where the intersection test is made
+         */
         public pickPosition: Vector2;
+
+        /**
+         * If true the intersection will stop at the first hit, if false all primitives will be tested and the intersectedPrimitives array will be filled accordingly (false default)
+         */
         public findFirstOnly: boolean;
+
+        /**
+         * If true the intersection test will also be made on hidden primitive (false default)
+         */
         public intersectHidden: boolean;
 
         // Intermediate data, don't use!
@@ -198,8 +254,20 @@
         public _localPickPosition: Vector2;
 
         // Output settings, up to date in return of a call to an intersection related method
+
+        /**
+         * The topmost intersected primitive
+         */
         public topMostIntersectedPrimitive: PrimitiveIntersectedInfo;
+
+        /**
+         * The array containing all intersected primitive, in no particular order.
+         */
         public intersectedPrimitives: Array<PrimitiveIntersectedInfo>;
+
+        /**
+         * true if at least one primitive intersected during the test
+         */
         public get isIntersected(): boolean {
             return this.intersectedPrimitives && this.intersectedPrimitives.length > 0;
         }
@@ -213,6 +281,9 @@
     }
 
     @className("Prim2DBase")
+    /**
+     * Base class for a Primitive of the Canvas2D feature
+     */
     export class Prim2DBase extends SmartPropertyPrim {
         static PRIM2DBASE_PROPCOUNT: number = 10;
 
@@ -256,6 +327,11 @@
             this.origin = new Vector2(0.5, 0.5);
         }
 
+        /**
+         * From 'this' primitive, traverse up (from parent to parent) until the given predicate is true
+         * @param predicate the predicate to test on each parent
+         * @return the first primitive where the predicate was successful
+         */
         public traverseUp(predicate: (p: Prim2DBase) => boolean): Prim2DBase {
             let p: Prim2DBase = this;
             while (p != null) {
@@ -267,18 +343,30 @@
             return null;
         }
 
+        /**
+         * Retrieve the owner Canvas2D
+         */
         public get owner(): Canvas2D {
             return this._owner;
         }
 
+        /**
+         * Get the parent primitive (can be the Canvas, only the Canvas has no parent)
+         */
         public get parent(): Prim2DBase {
             return this._parent;
         }
 
+        /**
+         * The array of direct children primitives
+         */
         public get children(): Prim2DBase[] {
             return this._children;
         }
 
+        /**
+         * The identifier of this primitive, may not be unique, it's for information purpose only
+         */
         public get id(): string {
             return this._id;
         }
@@ -292,6 +380,9 @@
         public static zOrderProperty: Prim2DPropInfo;
 
         @instanceLevelProperty(1, pi => Prim2DBase.positionProperty = pi, false, true)
+        /**
+         * Position of the primitive, relative to its parent.
+         */
         public get position(): Vector2 {
             return this._position;
         }
@@ -301,6 +392,10 @@
         }
 
         @instanceLevelProperty(2, pi => Prim2DBase.rotationProperty = pi, false, true)
+        /**
+         * Rotation of the primitive, in radian, along the Z axis
+         * @returns {} 
+         */
         public get rotation(): number {
             return this._rotation;
         }
@@ -310,6 +405,9 @@
         }
 
         @instanceLevelProperty(3, pi => Prim2DBase.scaleProperty = pi, false, true)
+        /**
+         * Uniform scale applied on the primitive
+         */
         public set scale(value: number) {
             this._scale = value;
         }
@@ -318,11 +416,6 @@
             return this._scale;
         }
 
-        @instanceLevelProperty(4, pi => Prim2DBase.originProperty = pi, false, true)
-        public set origin(value: Vector2) {
-            this._origin = value;
-        }
-
         /**
          * this method must be implemented by the primitive type to return its size
          * @returns The size of the primitive
@@ -331,13 +424,18 @@
             return undefined;
         }
 
+        @instanceLevelProperty(4, pi => Prim2DBase.originProperty = pi, false, true)
+        public set origin(value: Vector2) {
+            this._origin = value;
+        }
+
         /**
          * The origin defines the normalized coordinate of the center of the primitive, from the top/left corner.
          * The origin is used only to compute transformation of the primitive, it has no meaning in the primitive local frame of reference
          * For instance:
-         * 0,0 means the center is top/left
-         * 0.5,0.5 means the center is at the center of the primitive
-         * 0,1 means the center is bottom/left
+         * 0,0 means the center is bottom/left. Which is the default for Canvas2D instances
+         * 0.5,0.5 means the center is at the center of the primitive, which is default of all types of Primitives
+         * 0,1 means the center is top/left
          * @returns The normalized center.
          */
         public get origin(): Vector2 {
@@ -345,6 +443,10 @@
         }
 
         @dynamicLevelProperty(5, pi => Prim2DBase.levelVisibleProperty = pi)
+        /**
+         * Let the user defines if the Primitive is hidden or not at its level. As Primitives inherit the hidden status from their parent, only the isVisible property give properly the real visible state.
+         * Default is true, setting to false will hide this primitive and its children.
+         */
         public get levelVisible(): boolean {
             return this._levelVisible;
         }
@@ -354,6 +456,10 @@
         }
 
         @instanceLevelProperty(6, pi => Prim2DBase.isVisibleProperty = pi)
+        /**
+         * Use ONLY THE GETTER to determine if the primitive is visible or not.
+         * The Setter is for internal purpose only!
+         */
         public get isVisible(): boolean {
             return this._isVisible;
         }
@@ -363,6 +469,10 @@
         }
 
         @instanceLevelProperty(7, pi => Prim2DBase.zOrderProperty = pi)
+        /**
+         * You can override the default Z Order through this property, but most of the time the default behavior is acceptable
+         * @returns {} 
+         */
         public get zOrder(): number {
             return this._zOrder;
         }
@@ -371,6 +481,9 @@
             this._zOrder = value;
         }
 
+        /**
+         * Define if the Primitive can be subject to intersection test or not (default is true)
+         */
         public get isPickable(): boolean {
             return this._isPickable;
         }
@@ -379,27 +492,49 @@
             this._isPickable = value;
         }
 
+        /**
+         * Return the depth level of the Primitive into the Canvas' Graph. A Canvas will be 0, its direct children 1, and so on.
+         * @returns {} 
+         */
         public get hierarchyDepth(): number {
             return this._hierarchyDepth;
         }
 
+        /**
+         * Retrieve the Group that is responsible to render this primitive
+         * @returns {} 
+         */
         public get renderGroup(): Group2D {
             return this._renderGroup;
         }
 
+        /**
+         * Get the global transformation matrix of the primitive
+         */
         public get globalTransform(): Matrix {
             return this._globalTransform;
         }
 
+        /**
+         * Get invert of the global transformation matrix of the primitive
+         * @returns {} 
+         */
         public get invGlobalTransform(): Matrix {
             return this._invGlobalTransform;
         }
 
+        /**
+         * Get the local transformation of the primitive
+         */
         public get localTransform(): Matrix {
             this._updateLocalTransform();
             return this._localTransform;
         }
 
+        /**
+         * Get the boundingInfo associated to the primitive.
+         * The value is supposed to be always up to date
+         */
         public get boundingInfo(): BoundingInfo2D {
             if (this._boundingInfoDirty) {
                 this._boundingInfo = this.levelBoundingInfo.clone();
@@ -416,6 +551,9 @@
             return this._boundingInfo;
         }
 
+        /**
+         * Interaction with the primitive can be create using this Observable. See the PrimitivePointerInfo class for more information
+         */
         public get pointerEventObservable(): Observable<PrimitivePointerInfo> {
             return this._pointerEventObservable;
         }
@@ -425,6 +563,27 @@
             return false;
         }
 
+        /**
+         * Capture all the Events of the given PointerId for this primitive.
+         * Don't forget to call releasePointerEventsCapture when done.
+         * @param pointerId the Id of the pointer to capture the events from.
+         */
+        public setPointerEventCapture(pointerId: number): boolean {
+            return this.owner._setPointerCapture(pointerId, this);
+        }
+
+        /**
+         * Release a captured pointer made with setPointerEventCapture.
+         * @param pointerId the Id of the pointer to release the capture from.
+         */
+        public releasePointerEventsCapture(pointerId: number): boolean {
+            return this.owner._releasePointerCapture(pointerId, this);
+        }
+
+        /**
+         * Make an intersection test with the primitive, all inputs/outputs are stored in the IntersectInfo2D class, see its documentation for more information.
+         * @param intersectInfo contains the settings of the intersection to perform, to setup before calling this method as well as the result, available after a call to this method.
+         */
         public intersect(intersectInfo: IntersectInfo2D): boolean {
             if (!intersectInfo) {
                 return false;
@@ -556,7 +715,7 @@
             }
         }
 
-        public needPrepare(): boolean {
+        public _needPrepare(): boolean {
             return (this.isVisible || this._visibilityChanged) && (this._modelDirty || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep));
         }
 

+ 24 - 2
src/Tools/babylon.observable.ts

@@ -8,22 +8,44 @@
         /**
         * If the callback of a given Observer set skipNextObservers to true the following observers will be ignored
         */
-        constructor(public mask: number, public skipNextObservers = false) {
+        constructor(mask: number, skipNextObservers = false) {
+            this.mask = mask;
+            this.skipNextObservers = skipNextObservers;
         }
+
+        /**
+         * An Observer can set this property to true to prevent subsequent observers of being notified
+         */
+        public skipNextObservers: boolean;
+
+        /**
+         * Get the mask value that were used to trigger the event corresponding to this EventState object
+         */
+        public mask: number;
     }
 
+    /**
+     * Represent an Observer registered to a given Observable object.
+     */
     export class Observer<T> {
         constructor(public callback: (eventData: T, eventState: EventState) => void, public mask: number) {
         }
     }
 
+    /**
+     * The Observable class is a simple implementation of the Observable pattern.
+     * There's one slight particularity though: a given Observable can notify its observer using a particular mask value, only the Observers registered with this mask value will be notified.
+     * This enable a more fine grained execution without having to rely on multiple different Observable objects.
+     * For instance you may have a given Observable that have four different types of notifications: Move (mask = 0x01), Stop (mask = 0x02), Turn Right (mask = 0X04), Turn Left (mask = 0X08).
+     * A given observer can register itself with only Move and Stop (mask = 0x03), then it will only be notified when one of these two occurs and will never be for Turn Left/Right.
+     */
     export class Observable<T> {
         _observers = new Array<Observer<T>>();
 
         /**
          * Create a new Observer with the specified callback
          * @param callback the callback that will be executed for that Observer
-         * @param mash the mask used to filter observers
+         * @param mask the mask used to filter observers
          * @param insertFirst if true the callback will be inserted at the first position, hence executed before the others ones. If false (default behavior) the callback will be inserted at the last position, executed after all the others already present.
          */
         public add(callback: (eventData: T, eventState: EventState) => void, mask: number = -1, insertFirst = false): Observer<T> {