소스 검색

dispose meshes

Trevor Baron 6 년 전
부모
커밋
7fbe90abd9
1개의 변경된 파일99개의 추가작업 그리고 80개의 파일을 삭제
  1. 99 80
      src/Cameras/XR/webXRInput.ts

+ 99 - 80
src/Cameras/XR/webXRInput.ts

@@ -25,6 +25,8 @@ export class WebXRController {
      */
     public pointer: AbstractMesh;
 
+    public onDisposeObservable = new Observable<{}>();
+
     private _tmpMatrix = new Matrix();
     private _tmpQuaternion = new Quaternion();
     private _tmpVector = new Vector3();
@@ -61,7 +63,7 @@ export class WebXRController {
      * @param referenceSpace reference space to use
      */
     public updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace) {
-        var pose = xrFrame.getPose(this.inputSource.targetRaySpace, referenceSpace);
+        let pose = xrFrame.getPose(this.inputSource.targetRaySpace, referenceSpace);
 
         // Update the pointer mesh
         if (pose) {
@@ -77,7 +79,7 @@ export class WebXRController {
 
         // Update the grip mesh if it exists
         if (this.inputSource.gripSpace && this.grip) {
-            var pose = xrFrame.getPose(this.inputSource.gripSpace, referenceSpace);
+            let pose = xrFrame.getPose(this.inputSource.gripSpace, referenceSpace);
             if (pose) {
                 Matrix.FromFloat32ArrayToRefScaled(pose.transform.matrix, 0, 1, this._tmpMatrix);
                 if (!this.grip.getScene().useRightHandedSystem) {
@@ -97,7 +99,7 @@ export class WebXRController {
      */
     public getWorldPointerRayToRef(result:Ray){
         // Force update to ensure picked point is synced with ray
-        var worldMatrix = this.pointer.computeWorldMatrix(true)
+        let worldMatrix = this.pointer.computeWorldMatrix(true)
         worldMatrix.decompose(undefined, this._tmpQuaternion, undefined)
         this._tmpVector.set(0,0,1)
         this._tmpVector.rotateByQuaternionToRef(this._tmpQuaternion, this._tmpVector)
@@ -115,6 +117,7 @@ export class WebXRController {
             this.grip.dispose();
         }
         this.pointer.dispose();
+        this.onDisposeObservable.notifyObservers({});
     }
 }
 
@@ -166,18 +169,18 @@ export class WebXRInput implements IDisposable {
 
     private _addAndRemoveControllers(addInputs: Array<XRInputSource>, removeInputs: Array<XRInputSource>) {
         // Add controllers if they don't already exist
-        var sources = this.controllers.map((c) => {return c.inputSource; });
-        for(var input of addInputs){
+        let sources = this.controllers.map((c) => {return c.inputSource; });
+        for(let input of addInputs){
             if (sources.indexOf(input) === -1) {
-                var controller = new WebXRController(this.xrExperienceHelper.camera._scene, input, this.xrExperienceHelper.container);
+                let controller = new WebXRController(this.xrExperienceHelper.camera._scene, input, this.xrExperienceHelper.container);
                 this.controllers.push(controller);
                 this.onControllerAddedObservable.notifyObservers(controller);
             }
         }
 
         // Remove and dispose of controllers to be disposed
-        var keepControllers: Array<WebXRController> = [];
-        var removedControllers: Array<WebXRController> = [];
+        let keepControllers: Array<WebXRController> = [];
+        let removedControllers: Array<WebXRController> = [];
         this.controllers.forEach((c) => {
             if (removeInputs.indexOf(c.inputSource) === -1) {
                 keepControllers.push(c);
@@ -255,86 +258,93 @@ export class WebXRControllerPointerSelection {
     constructor(input: WebXRInput){
         
         input.onControllerAddedObservable.add((c)=>{
-            var scene = c.pointer.getScene();
+            let scene = c.pointer.getScene();
 
-            let _laserPointer: Mesh;
-            let _cursorMesh: Mesh;
+            let laserPointer: Mesh;
+            let cursorMesh: Mesh;
             let triggerDown = false;
-            let _id:number;
-            _id = WebXRControllerPointerSelection._idCounter++;
+            let id:number;
+            id = WebXRControllerPointerSelection._idCounter++;
 
             // Create a laser pointer for the XR controller
-            _laserPointer = Mesh.CreateCylinder("laserPointer", 1, 0.0002, 0.004, 20, 1, scene, false);
-            _laserPointer.parent = c.pointer
-            var laserPointerMaterial = new StandardMaterial("laserPointerMat", scene);
+            laserPointer = Mesh.CreateCylinder("laserPointer", 1, 0.0002, 0.004, 20, 1, scene, false);
+            laserPointer.parent = c.pointer
+            let laserPointerMaterial = new StandardMaterial("laserPointerMat", scene);
             laserPointerMaterial.emissiveColor = new Color3(0.7, 0.7, 0.7);
             laserPointerMaterial.alpha = 0.6;
-            _laserPointer.material = laserPointerMaterial;
-            _laserPointer.rotation.x = Math.PI / 2;
-            this._updatePointerDistance(_laserPointer,1)
-            _laserPointer.isPickable = false;
+            laserPointer.material = laserPointerMaterial;
+            laserPointer.rotation.x = Math.PI / 2;
+            this._updatePointerDistance(laserPointer,1)
+            laserPointer.isPickable = false;
 
             // Create a gaze tracker for the  XR controlelr
-            _cursorMesh = Mesh.CreateTorus("gazeTracker", 0.0035*3, 0.0025*3, 20, scene, false);
-            _cursorMesh.bakeCurrentTransformIntoVertices();
-            _cursorMesh.isPickable = false;
-            _cursorMesh.isVisible = false;
-            var targetMat = new StandardMaterial("targetMat", scene);
+            cursorMesh = Mesh.CreateTorus("gazeTracker", 0.0035*3, 0.0025*3, 20, scene, false);
+            cursorMesh.bakeCurrentTransformIntoVertices();
+            cursorMesh.isPickable = false;
+            cursorMesh.isVisible = false;
+            let targetMat = new StandardMaterial("targetMat", scene);
             targetMat.specularColor = Color3.Black();
             targetMat.emissiveColor = new Color3(0.7, 0.7, 0.7);
             targetMat.backFaceCulling = false;
-            _cursorMesh.material = targetMat;
+            cursorMesh.material = targetMat;
 
-            scene.onBeforeRenderObservable.add(()=>{     
+            let renderObserver = scene.onBeforeRenderObservable.add(()=>{     
                 // Every frame check collisions/input        
                 c.getWorldPointerRayToRef(this._tmpRay)
-                var pick = scene.pickWithRay(this._tmpRay)
+                let pick = scene.pickWithRay(this._tmpRay)
                 if(pick){
                     if(c.inputSource.gamepad && c.inputSource.gamepad.buttons[0] && c.inputSource.gamepad.buttons[0].value > 0.7){
                         if(!triggerDown){
-                            scene.simulatePointerDown(pick, { pointerId: _id });
+                            scene.simulatePointerDown(pick, { pointerId: id });
                         }
                         triggerDown = true;
                     }else{
                         if(triggerDown){
-                            scene.simulatePointerUp(pick, { pointerId: _id });
+                            scene.simulatePointerUp(pick, { pointerId: id });
                         }
                         triggerDown = false;
                     }
-                    scene.simulatePointerMove(pick, { pointerId: _id });
+                    scene.simulatePointerMove(pick, { pointerId: id });
                 }
                 
                 if(pick && pick.pickedPoint && pick.hit){
                     // Update laser state
-                    this._updatePointerDistance(_laserPointer, pick.distance)
+                    this._updatePointerDistance(laserPointer, pick.distance)
 
                     // Update cursor state
-                    _cursorMesh.position.copyFrom(pick.pickedPoint)
-                    _cursorMesh.scaling.x = Math.sqrt(pick.distance);
-                    _cursorMesh.scaling.y = Math.sqrt(pick.distance);
-                    _cursorMesh.scaling.z = Math.sqrt(pick.distance);
+                    cursorMesh.position.copyFrom(pick.pickedPoint)
+                    cursorMesh.scaling.x = Math.sqrt(pick.distance);
+                    cursorMesh.scaling.y = Math.sqrt(pick.distance);
+                    cursorMesh.scaling.z = Math.sqrt(pick.distance);
 
                     // To avoid z-fighting
-                    var pickNormal = this._convertNormalToDirectionOfRay(pick.getNormal(), this._tmpRay);
+                    let pickNormal = this._convertNormalToDirectionOfRay(pick.getNormal(), this._tmpRay);
                     let deltaFighting = 0.002;
-                    _cursorMesh.position.copyFrom(pick.pickedPoint);
+                    cursorMesh.position.copyFrom(pick.pickedPoint);
                     if (pickNormal) {
-                        var axis1 = Vector3.Cross(Axis.Y, pickNormal);
-                        var axis2 = Vector3.Cross(pickNormal, axis1);
-                        Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, _cursorMesh.rotation);
-                        _cursorMesh.position.addInPlace(pickNormal.scale(deltaFighting));
+                        let axis1 = Vector3.Cross(Axis.Y, pickNormal);
+                        let axis2 = Vector3.Cross(pickNormal, axis1);
+                        Vector3.RotationFromAxisToRef(axis2, pickNormal, axis1, cursorMesh.rotation);
+                        cursorMesh.position.addInPlace(pickNormal.scale(deltaFighting));
                     }
-                    _cursorMesh.isVisible = true;
+                    cursorMesh.isVisible = true;
                 }else{
-                    _cursorMesh.isVisible = false;
+                    cursorMesh.isVisible = false;
                 }
             })
+
+            c.onDisposeObservable.addOnce(()=>{
+                laserPointer.dispose();
+                cursorMesh.dispose();
+
+                scene.onBeforeRenderObservable.remove(renderObserver)
+            })
         })
     }
 
     private _convertNormalToDirectionOfRay(normal: Nullable<Vector3>, ray: Ray) {
         if (normal) {
-            var angle = Math.acos(Vector3.Dot(normal, ray.direction));
+            let angle = Math.acos(Vector3.Dot(normal, ray.direction));
             if (angle < Math.PI / 2) {
                 normal.scaleInPlace(-1);
             }
@@ -365,23 +375,23 @@ export class WebXRControllerTeleportation {
      */
     constructor(input: WebXRInput, public floorMeshes:Array<AbstractMesh> = []){
         input.onControllerAddedObservable.add((c)=>{
-            var scene = c.pointer.getScene();
+            let scene = c.pointer.getScene();
 
-            var _forwardReadyToTeleport = false;
-            var _backwardReadyToTeleport = false;
-            var _leftReadyToTeleport = false;
-            var _rightReadyToTeleport = false;
+            let forwardReadyToTeleport = false;
+            let backwardReadyToTeleport = false;
+            let leftReadyToTeleport = false;
+            let rightReadyToTeleport = false;
 
             // Teleport target abd it's animation
-            var teleportationTarget = Mesh.CreateGround("teleportationTarget", 2, 2, 2, scene);
+            let teleportationTarget = Mesh.CreateGround("teleportationTarget", 2, 2, 2, scene);
             teleportationTarget.isPickable = false;
-            var length = 512;
-            var dynamicTexture = new DynamicTexture("DynamicTexture", length, scene, true);
+            let length = 512;
+            let dynamicTexture = new DynamicTexture("DynamicTexture", length, scene, true);
             dynamicTexture.hasAlpha = true;
-            var context = dynamicTexture.getContext();
-            var centerX = length / 2;
-            var centerY = length / 2;
-            var radius = 200;
+            let context = dynamicTexture.getContext();
+            let centerX = length / 2;
+            let centerY = length / 2;
+            let radius = 200;
             context.beginPath();
             context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
             context.fillStyle = this._teleportationFillColor;
@@ -391,14 +401,14 @@ export class WebXRControllerTeleportation {
             context.stroke();
             context.closePath();
             dynamicTexture.update();
-            var teleportationCircleMaterial = new StandardMaterial("TextPlaneMaterial", scene);
+            let teleportationCircleMaterial = new StandardMaterial("TextPlaneMaterial", scene);
             teleportationCircleMaterial.diffuseTexture = dynamicTexture;
             teleportationTarget.material = teleportationCircleMaterial;
-            var torus = Mesh.CreateTorus("torusTeleportation", 0.75, 0.1, 25, scene, false);
+            let torus = Mesh.CreateTorus("torusTeleportation", 0.75, 0.1, 25, scene, false);
             torus.isPickable = false;
             torus.parent = teleportationTarget;
-            var animationInnerCircle = new Animation("animationInnerCircle", "position.y", 30, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE);
-            var keys = [];
+            let animationInnerCircle = new Animation("animationInnerCircle", "position.y", 30, Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CYCLE);
+            let keys = [];
             keys.push({
                 frame: 0,
                 value: 0
@@ -412,7 +422,7 @@ export class WebXRControllerTeleportation {
                 value: 0
             });
             animationInnerCircle.setKeys(keys);
-            var easingFunction = new SineEase();
+            let easingFunction = new SineEase();
             easingFunction.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);
             animationInnerCircle.setEasingFunction(easingFunction);
             torus.animations = [];
@@ -420,11 +430,11 @@ export class WebXRControllerTeleportation {
             scene.beginAnimation(torus, 0, 60, true);
 
             // Handle user input on every frame
-            scene.onBeforeRenderObservable.add(()=>{
+            let renderObserver = scene.onBeforeRenderObservable.add(()=>{
                 // Move the teleportationTarget to where the user is targetting to teleport to
-                if(_forwardReadyToTeleport){
+                if(forwardReadyToTeleport){
                     c.getWorldPointerRayToRef(this._tmpRay)
-                    var pick = scene.pickWithRay(this._tmpRay, (o)=>{
+                    let pick = scene.pickWithRay(this._tmpRay, (o)=>{
                         return floorMeshes.indexOf(o) !== -1;
                     })
                     if(pick && pick.pickedPoint){
@@ -443,25 +453,25 @@ export class WebXRControllerTeleportation {
                     if(c.inputSource.gamepad.axes[1]){
                         // Forward teleportation
                         if(c.inputSource.gamepad.axes[1] < -0.7){
-                            _forwardReadyToTeleport = true
+                            forwardReadyToTeleport = true
                         }else{
-                            if(_forwardReadyToTeleport){
+                            if(forwardReadyToTeleport){
                                 // Teleport the users feet to where they targetted
                                 this._tmpVector.copyFrom(teleportationTarget.position)
                                 this._tmpVector.y += input.xrExperienceHelper.camera.position.y;
                                 input.xrExperienceHelper.setPositionOfCameraUsingContainer(this._tmpVector)
                             }
-                            _forwardReadyToTeleport = false
+                            forwardReadyToTeleport = false
                         }
 
                         // Backward teleportation
                         if(c.inputSource.gamepad.axes[1] > 0.7){
-                            _backwardReadyToTeleport = true
+                            backwardReadyToTeleport = true
                         }else{
-                            if(_backwardReadyToTeleport){
+                            if(backwardReadyToTeleport){
                                 // Cast a ray down from behind the user
-                                var camMat = input.xrExperienceHelper.camera.computeWorldMatrix();
-                                var q = new Quaternion()
+                                let camMat = input.xrExperienceHelper.camera.computeWorldMatrix();
+                                let q = new Quaternion()
                                 camMat.decompose(undefined, q, this._tmpRay.origin)
                                 this._tmpVector.set(0,0,-1);
                                 this._tmpVector.rotateByQuaternionToRef(q, this._tmpVector)
@@ -470,7 +480,7 @@ export class WebXRControllerTeleportation {
                                 this._tmpVector.y = -1.5;
                                 this._tmpVector.normalize()
                                 this._tmpRay.direction.copyFrom(this._tmpVector)
-                                var pick = scene.pickWithRay(this._tmpRay, (o)=>{
+                                let pick = scene.pickWithRay(this._tmpRay, (o)=>{
                                     return floorMeshes.indexOf(o) !== -1;
                                 })
 
@@ -481,31 +491,40 @@ export class WebXRControllerTeleportation {
                                     input.xrExperienceHelper.setPositionOfCameraUsingContainer(this._tmpVector)
                                 }
                             }
-                            _backwardReadyToTeleport = false
+                            backwardReadyToTeleport = false
                         }
                     }
 
                     if(c.inputSource.gamepad.axes[0]){
                         if(c.inputSource.gamepad.axes[0] < -0.7){
-                            _leftReadyToTeleport = true
+                            leftReadyToTeleport = true
                         }else{
-                            if(_leftReadyToTeleport){
+                            if(leftReadyToTeleport){
                                 input.xrExperienceHelper.rotateCameraByQuaternionUsingContainer(Quaternion.FromEulerAngles(0, -Math.PI/4, 0))
                             }
-                            _leftReadyToTeleport = false
+                            leftReadyToTeleport = false
                         }
                         if(c.inputSource.gamepad.axes[0] > 0.7){
-                            _rightReadyToTeleport = true
+                            rightReadyToTeleport = true
                         }else{
-                            if(_rightReadyToTeleport){
+                            if(rightReadyToTeleport){
                                 input.xrExperienceHelper.rotateCameraByQuaternionUsingContainer(Quaternion.FromEulerAngles(0, Math.PI/4, 0))
                             }
-                            _rightReadyToTeleport = false
+                            rightReadyToTeleport = false
                         }
                     }
                     
                 }
             })
+
+            c.onDisposeObservable.addOnce(()=>{
+                teleportationTarget.dispose()
+                dynamicTexture.dispose()
+                teleportationCircleMaterial.dispose()
+                torus.dispose()
+
+                scene.onBeforeRenderObservable.remove(renderObserver);
+            })
         })
     }