ssaket 6 rokov pred
rodič
commit
b0f54bce1c

+ 23 - 3
dist/preview release/what's new.md

@@ -13,21 +13,26 @@
   - webXRExperienceHelper to setup a default XR experience ([TrevorDev](https://github.com/TrevorDev))
   - WebXREnterExitUI and WebXRManagedOutputCanvas classes to configure the XR experience ([TrevorDev](https://github.com/TrevorDev))
   - WebXRInput manage controllers for the XR experience ([TrevorDev](https://github.com/TrevorDev))
+  - WebXR camera rotation using parent container ([TrevorDev](https://github.com/TrevorDev))
 - GUI:
   - Added new [ImageBasedSlider](http://doc.babylonjs.com/how_to/gui#imagebasedslider) to let users customize sliders using images ([Deltakosh](https://github.com/deltakosh))
-  - Added new Clipboard events [Saket Saurabh](https://github.com/ssaket)
+  - Added support for clipboard events to let users perform `cut`, `copy` and `paste` events ([Saket Saurabh](https://github.com/ssaket))
 
 ## Updates
 
 ### GUI
 
 - Added `button.image` and `button.textBlock` to simplify access to button internal parts ([Deltakosh](https://github.com/deltakosh))
+- Added support for performing operations like select all, text highlight, delete selected in `inputText` ([Saket Saurabh](https://github.com/ssaket))
+- Added `inputText.onTextCopyObservable`, `inputText.onTextCutObservable` and `inputText.onTextPasteObservable` to inputText ([Saket Saurabh](https://github.com/ssaket))
+- Added `AdvancedDynamicTexture.onClipboardObservable` to observe for clipboard events in AdvancedDynamicTexture([Saket Saurabh](https://github.com/ssaket))
 - Added `sldier.displayThumb` to show/hide slider's thumb ([Deltakosh](https://github.com/deltakosh))
 - Added `grid.rowCount`, `grid.columnCount` and `grid.getChildrenAt()` ([Deltakosh](https://github.com/deltakosh))
-- Added clipboard event `cut`, `copy`, `paste` to AdvanceDynamicTexture ([Saket Saurabh](https://github.com/ssaket]))
+- Added `Control.AllowAlphaInheritance` to let users control the way alpha is used (inherited or not) ([Deltakosh](https://github.com/deltakosh))
 
 ### Core Engine
 
+- Added support for utility layer for SkeletonViewer ([Deltakosh](https://github.com/deltakosh))
 - Improved shader precision detection ([Deltakosh](https://github.com/deltakosh))
 - Added support for bone matrix texture. Now skeletons will use a texture instead of uniforms when possible ([Deltakosh](https://github.com/deltakosh))
 - Refactored of the SolidParticleSystem code for performance and code quality improvement ([barroij](https://github.com/barroij))
@@ -48,9 +53,13 @@
   - Added an `Vector3.UnprojectRayToRef` static function to avoid computing and inverting the projection matrix twice when updating a Ray.
 - Align `BoundingBox` and `BoundingSphere` API and behavior for clarity and simplicity. As a consequence, the `BoundingBox`'s method `setWorldMatrix` has been removed and the underlying world matrix cannot be modified but by calling `reConstruct` or `update`. ([barroij](https://github.com/barroij))
 - Make sure that `Material.markAsDirty` and all the `markXXXDirty` methods early out when `scene.blockMaterialDirtyMechanism` is true. ([barroij](https://github.com/barroij))
+- Add updateUpVectorFromRotation to target camera to allow the up vector to be computed from rotation ([TrevorDev](https://github.com/TrevorDev))
 
 ### glTF Loader
 
+- Added support for mesh instancing for improved performance when multiple nodes point to the same mesh ([bghgary](https://github.com/bghgary))
+- Create `TransformNode` objects instead of `Mesh` objects for glTF nodes without geometry ([bghgary](https://github.com/bghgary))
+
 ### glTF Serializer
 
 ### Viewer
@@ -58,13 +67,19 @@
 ### Materials Library
 
 ## Bug fixes
+- Removed bones from rootNodes where they should never have been ([Deltakosh](https://github.com/deltakosh))
 - Refocusing on input gui with pointer events ([TrevorDev](https://github.com/TrevorDev))
+- Gizmo scaling not consistent when camera is parented ([TrevorDev](https://github.com/TrevorDev))
+- Context loss causing unexpected results with dynamic textures ([TrevorDev](https://github.com/TrevorDev))
+- CreateScreenshotUsingRenderTarget stretches mirror textures when setting both width and height ([TrevorDev](https://github.com/TrevorDev))
+- VR helper only updating vr cameras position when entering vr, rotation was missing ([TrevorDev](https://github.com/TrevorDev))
+- Fix VR controllers after gltfLoader transformNode change ([TrevorDev](https://github.com/TrevorDev))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with pointer up being fire twice ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with particle systems being update once per camera instead of once per frame ([Deltakosh](https://github.com/deltakosh))
-- Handle properly the `LinesMesh` `intersectionThreshold` by using its value directly when the intersection against a `Ray` is checked, instead of extending the `BoundingInfo` accordingly ([barroij](https://github.com/barroij))
+- Handle properly the `LinesMesh` `intersectionThreshold` by using its value directly when the intersection against a `Ray` is checked, instead of extending the `BoundingInfo` accordingly + Addded an `InstancesLinesMesh` class used to create instance of `LinesMesh` so that each instance can have its own `intersectionThreshold` value ([barroij](https://github.com/barroij))
 - Fixed the `LineEdgesRenderer` used for edge rendering of `LinesMesh` handle properly LinesMesh made of disconnected lines + Make it work for instance of `LinesMesh` ([barroij](https://github.com/barroij))
 - Fixed `Matrix.toNormalMatrix`function ([barroij](https://github.com/barroij))
 - Add missing effect layer to asset container ([TrevorDev](https://github.com/TrevorDev))
@@ -99,3 +114,8 @@
   - `engine.drawCallsPerfCounter`: use SceneInstrumentation class instead
   - `shadowGenerator.useVarianceShadowMap`: use useExponentialShadowMap instead
   - `shadowGenerator.useBlurVarianceShadowMap`: use useBlurExponentialShadowMap instead
+- The glTF loader now creates `InstancedMesh` objects when two nodes point to the same mesh ([bghgary](https://github.com/bghgary))
+- The glTF loader now creates `TransformNode` objects instead of `Mesh` objects for glTF nodes without geometry ([bghgary](https://github.com/bghgary))
+  - _Note: The root node is still a `Mesh` object and is still the first in the returned list of meshes_
+  - `TransformNode` objects are excluded from the returned list of meshes when importing mesh
+  - `TransformNode` objects do not raise `onMeshLoaded` events

+ 4 - 21
gui/src/2D/advancedDynamicTexture.ts

@@ -17,13 +17,10 @@ export interface IFocusableControl {
      */
     onBlur(): void;
     /**
-     * Function called to let the control handle events,
-     * KeyboardEvent -> handles key events
-     * PointerEvent -> handles dbl click event and text highlight.
-     * ClipboardInfo -> handles copy, cut, paste events.
-     * @param evt Defines the base Event object, can be (PointerEvent, KeyboardEvent and ClipboardEvent)
+     * Function called to let control handle key events
+     * @param evt Defines the  KeyboardEvent object
      */
-    processKeyboard(evt: Event): void;
+    processKeyboard(evt: KeyboardEvent): void;
 
     /**
      * Function called to get the list of controls that should not steal the focus from this control
@@ -617,14 +614,6 @@ export class AdvancedDynamicTexture extends DynamicTexture {
             if (scene!.isPointerCaptured((<PointerEvent>(pi.event)).pointerId)) {
                 return;
             }
-            //check for focused control and call the onClipboardPointerEvents
-            if (this._focusedControl) {
-                if (pi.type === PointerEventTypes.POINTERDOUBLETAP) {
-                    this._focusedControl.processKeyboard(pi.event);
-                    return;
-                }
-
-            }
 
             if (pi.type !== PointerEventTypes.POINTERMOVE
                 && pi.type !== PointerEventTypes.POINTERUP
@@ -656,13 +645,6 @@ export class AdvancedDynamicTexture extends DynamicTexture {
             }
         });
 
-        this.onClipboardObservable.add((pi, state) => {
-            if (this.focusedControl) {
-                // call the event's callback
-                this.focusedControl.processKeyboard(pi.event);
-            }
-        });
-
         this._attachToOnPointerOut(scene);
     }
 
@@ -682,6 +664,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     private onClipboardPaste = (evt: ClipboardEvent) => {
         let ev = new ClipboardInfo(ClipboardEventTypes.PASTE, evt);
         this.onClipboardObservable.notifyObservers(ev);
+        evt.preventDefault();
     }
 
    /**

+ 87 - 65
gui/src/2D/controls/inputText.ts

@@ -1,7 +1,7 @@
 import { Control } from "./control";
 import { IFocusableControl } from "../advancedDynamicTexture";
 import { ValueAndUnit } from "../valueAndUnit";
-import { Nullable, Observable, Vector2, ClipboardEventTypes, ClipboardInfo } from "babylonjs";
+import { Nullable, Observable, Observer, Vector2, ClipboardEventTypes, ClipboardInfo, PointerInfo } from 'babylonjs';
 import { Measure } from "../measure";
 import { VirtualKeyboard } from "./virtualKeyboard";
 
@@ -34,6 +34,8 @@ export class InputText extends Control implements IFocusableControl {
     private _highlightedText = "";
     private _startHighlightIndex = 0;
     private _endHighlightIndex = 0;
+    private _onClipboardObserver: Nullable<Observer<ClipboardInfo>>;
+    private _onPointerDblTapObserver: Nullable<Observer<PointerInfo>>;
 
     /** @hidden */
     public _connectedVirtualKeyboard: Nullable<VirtualKeyboard>;
@@ -49,6 +51,14 @@ export class InputText extends Control implements IFocusableControl {
     public onFocusObservable = new Observable<InputText>();
     /** Observable raised when the control loses the focus */
     public onBlurObservable = new Observable<InputText>();
+    /**Observable raised when the text is highlighted */
+    public onTextHighlightObservable = new Observable<InputText>();
+    /**Observable raised when copy event is triggered */
+    public onTextCopyObservable = new Observable<InputText>();
+    /** Observable raised when cut event is triggered */
+    public onTextCutObservable = new Observable<InputText>();
+    /** Observable raised when paste event is triggered */
+    public onTextPasteObservable = new Observable<InputText>();
 
     /** Gets or sets the maximum width allowed by the control */
     public get maxWidth(): string | number {
@@ -292,6 +302,13 @@ export class InputText extends Control implements IFocusableControl {
         this.onBlurObservable.notifyObservers(this);
 
         this._host.unRegisterClipboardEvents();
+        if (this._onClipboardObserver) {
+            this._host.onClipboardObservable.remove(this._onClipboardObserver);
+        }
+        let scene = this._host.getScene();
+        if (this._onPointerDblTapObserver && scene) {
+            scene.onPointerObservable.remove(this._onPointerDblTapObserver);
+        }
     }
 
     /** @hidden */
@@ -319,6 +336,38 @@ export class InputText extends Control implements IFocusableControl {
 
         this._host.registerClipboardEvents();
 
+        this._onClipboardObserver = this._host.onClipboardObservable.add((clipboardInfo) => {
+            // process clipboard event, can be configured.
+             switch (clipboardInfo.type){
+                 case ClipboardEventTypes.COPY:
+                         this._onCopyText(clipboardInfo.event);
+                         this.onTextCopyObservable.notifyObservers(this);
+                         break;
+                 case ClipboardEventTypes.CUT:
+                         this._onCutText(clipboardInfo.event);
+                         this.onTextCutObservable.notifyObservers(this);
+                         break;
+                 case ClipboardEventTypes.PASTE:
+                         this._onPasteText(clipboardInfo.event);
+                         this.onTextPasteObservable.notifyObservers(this);
+                         break;
+                 default: return;
+              }
+        });
+
+        let scene = this._host.getScene();
+        if (scene) {
+            //register the pointer double tap event
+            this._onPointerDblTapObserver = scene.onPointerObservable.add((pointerInfo) => {
+                if (!this._isFocused) {
+                    return;
+                }
+                if (pointerInfo.type === BABYLON.PointerEventTypes.POINTERDOUBLETAP) {
+                    this._processDblClick(pointerInfo);
+                }
+            });
+        }
+
     }
 
     protected _getTypeName(): string {
@@ -339,20 +388,26 @@ export class InputText extends Control implements IFocusableControl {
     /** @hidden */
     public processKey(keyCode: number, key?: string, evt?: KeyboardEvent) {
 
-        //get the clipboard Event from the keycode, returns -1 if not found.
-        let clipboardEventType: ClipboardEventTypes = ClipboardInfo.GetTypeFromCharacter(keyCode);
-        if (evt && (evt.ctrlKey || evt.metaKey) && clipboardEventType !== -1) {
+        //return if clipboard event keys (i.e -ctr/cmd + c,v,x)
+        if (evt && (evt.ctrlKey || evt.metaKey) && (keyCode === 67 || keyCode === 86 || keyCode === 88)) {
             return;
         }
 
         //select all
         if (evt && (evt.ctrlKey || evt.metaKey) && keyCode === 65) {
+
+            this._blinkIsEven = false;
+            this._isTextHighlightOn = true;
+            evt.preventDefault();
+
+            //if already highlighted pass
+            if (this._highlightedText) {
+                return;
+            }
+
             this._startHighlightIndex = 0;
             this._endHighlightIndex = this._text.length;
-            this._isTextHighlightOn = true;
-            this._blinkIsEven = true;
             this._cursorOffset = 0;
-            evt.preventDefault();
             return;
         }
         // Specific cases
@@ -378,7 +433,7 @@ export class InputText extends Control implements IFocusableControl {
                         }
                         return;
                     }
-                    //delete individual character
+                    //delete single character
                     if (this._cursorOffset === 0) {
                         this.text = this._text.substr(0, this._text.length - 1);
                     } else {
@@ -493,7 +548,7 @@ export class InputText extends Control implements IFocusableControl {
         }
     }
     /** @hidden */
-    private _processDblClick(evt: PointerEvent) {
+    private _processDblClick(evt: PointerInfo) {
         //pre-find the start and end index of the word under cursor, speeds up the rendering
         this._startHighlightIndex = this._text.length - this._cursorOffset;
         this._endHighlightIndex = this._startHighlightIndex;
@@ -501,49 +556,35 @@ export class InputText extends Control implements IFocusableControl {
             right = (this._text[this._endHighlightIndex].search(rWord) !== -1) ? ++this._endHighlightIndex : 0;
             left =  (this._text[this._startHighlightIndex - 1 ].search(rWord) !== -1) ? --this._startHighlightIndex : 0;
         }
+        this.onTextHighlightObservable.notifyObservers(this);
         this._isTextHighlightOn = true;
         this._blinkIsEven = false;
     }
 
     /**
-     * Called by the onClipboardObservable of AdvanceDynamicTexture
-     * @param evt Event object
+     * Handles the keyboard event
+     * @param evt Defines the KeyboardEvent
      */
-    public processKeyboard(evt: KeyboardEvent | PointerEvent | ClipboardEvent): void {
-        // check the event type and call its action
-        if (evt instanceof KeyboardEvent) {
-            this.processKey(evt.keyCode, evt.key, evt);
-        }
-        else if (evt instanceof PointerEvent) {
-            this._processDblClick(evt);
-            evt.preventDefault();
-        }
-        else if (evt instanceof ClipboardEvent) {
-            this._processClipboardEvent(evt);
-            evt.preventDefault();
-        }
+    public processKeyboard(evt: KeyboardEvent): void {
+        // process pressed key
+        this.processKey(evt.keyCode, evt.key, evt);
     }
 
-    /**
-     * Callback in case of copy event, can be configured.
-     * @param ev ClipboardEvent
-     */
-    public onCopyText(ev: ClipboardEvent): void {
+    /** @hidden */
+    private _onCopyText(ev: ClipboardEvent): void {
         this._isTextHighlightOn = false;
         //when write permission to clipbaord data is denied
         try {
             ev.clipboardData.setData("text/plain", this._highlightedText);
         }
-        catch {
-            //pass
-        }
+        catch {} //pass
         this._host.clipboardData = this._highlightedText;
     }
-    /**
-     * Callback in case of cut event, can be configured.
-     * @param ev ClipboardEvent
-     */
-    public onCutText(ev: ClipboardEvent): void {
+    /** @hidden */
+    private _onCutText(ev: ClipboardEvent): void {
+        if (!this._highlightedText) {
+            return;
+        }
         this.text = this._text.slice(0, this._startHighlightIndex) + this._text.slice(this._endHighlightIndex);
         this._isTextHighlightOn = false;
         this._cursorOffset = this.text.length - this._startHighlightIndex;
@@ -551,48 +592,25 @@ export class InputText extends Control implements IFocusableControl {
         try {
             ev.clipboardData.setData("text/plain", this._highlightedText);
         }
-        catch {
-            //pass
-        }
+        catch { } //pass
 
         this._host.clipboardData = this._highlightedText;
+        this._highlightedText = "";
     }
-    /**
-     * Callback in case of paste event, can be configured.
-     * @param ev ClipboardEvent
-     */
-    public onPasteText(ev: ClipboardEvent): void {
+    /** @hidden */
+    private _onPasteText(ev: ClipboardEvent): void {
         let data: string = "";
         if (ev.clipboardData && ev.clipboardData.types.indexOf("text/plain") !== -1) {
             data = ev.clipboardData.getData("text/plain");
         }
         else {
+            //get the cached data; returns blank string by default
             data = this._host.clipboardData;
         }
         let insertPosition = this._text.length - this._cursorOffset;
         this.text = this._text.slice(0, insertPosition) + data + this._text.slice(insertPosition);
     }
 
-    /**
-     * @hidden
-     * Currently placed at control level but can be moved to ADT if required.
-    */
-    private _processClipboardEvent(ev: ClipboardEvent): void {
-        // call the clipboard event's callback, invoked by ADT's onClipboardObserver
-         switch (ev.type){
-            case "copy":
-                    this.onCopyText(ev);
-                    break;
-            case "cut":
-                    this.onCutText(ev);
-                    break;
-            case "paste":
-                    this.onPasteText(ev);
-                    break;
-            default: return;
-         }
-    }
-
     public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
         context.save();
 
@@ -787,5 +805,9 @@ export class InputText extends Control implements IFocusableControl {
         this.onBlurObservable.clear();
         this.onFocusObservable.clear();
         this.onTextChangedObservable.clear();
+        this.onTextCopyObservable.clear();
+        this.onTextCutObservable.clear();
+        this.onTextPasteObservable.clear();
+        this.onTextHighlightObservable.clear();
     }
 }