import { Camera , CameraClearFlags } from "laya/d3/core/Camera" ; import { Scene3D } from "laya/d3/core/scene/Scene3D" ; import { Vector3 } from "laya/d3/math/Vector3" ; import { Vector4 } from "laya/d3/math/Vector4" ; import { Stage } from "laya/display/Stage" ; import { Button } from "laya/ui/Button" ; import { Browser } from "laya/utils/Browser" ; import { Handler } from "laya/utils/Handler" ; import { Stat } from "laya/utils/Stat" ; import { Laya3D } from "Laya3D" ; import { CameraMoveScript } from "../common/CameraMoveScript" ; import { Event } from "laya/events/Event" ; import { Sprite3D } from "laya/d3/core/Sprite3D" ; import { glTFLoader } from "laya/gltf/glTFLoader" ; import { PixelLineSprite3D } from "laya/d3/core/pixelLine/PixelLineSprite3D" ; import { Vector2 } from "laya/d3/math/Vector2" ; import { WebXRCameraInfo , WebXRExperienceHelper } from "laya/d3/WebXR/core/WebXRExperienceHelper" ; import { WebXRInputManager } from "laya/d3/WebXR/core/WebXRInputManager" ; import { WebXRInput } from "laya/d3/WebXR/core/WebXRInput" ; import { AxiGamepad , ButtonGamepad } from "laya/d3/WebXR/core/WebXRGamepad" ; import { Laya } from "Laya" ; import { Loader } from "laya/net/Loader" ; import { HitResult } from "laya/d3/physics/HitResult" ; export class WebXRControllerDemo { public camera : Camera ; public scene : Scene3D ; public isLeftSelectTarget : boolean = false ; public isRightSelectTarget : boolean = false ; public leftTarget : Sprite3D ; public rightTarget : Sprite3D ; public rotateStrength : number = 0 ; public leftTargetDistance : number = 3 ; public rightTargetDistance : number = 3 ; constructor ( ) { Laya3D . init ( 0 , 0 ) ; Stat . show ( ) ; Laya . stage . scaleMode = Stage . SCALE_FULL ; Laya . stage . screenMode = Stage . SCREEN_NONE ; glTFLoader . init ( ) ; this . PreloadingRes ( ) ; } PreloadingRes ( ) { var resource = [ "res/VRscene/Conventional/SampleScene.ls" , "res/OculusController/controller-left.gltf" , "res/OculusController/controller.gltf" ] ; Laya . loader . create ( resource , Handler . create ( this , this . onPreLoadFinish ) ) ; } onPreLoadFinish ( ) { let scene = Loader . getRes ( "res/VRscene/Conventional/SampleScene.ls" ) ; ( < Scene3D > Laya . stage . addChild ( scene ) ) ; this . scene = scene ; this . camera = ( < Camera > scene . getChildByName ( "Main Camera" ) ) ; this . camera . transform . rotate ( new Vector3 ( 0 , 0 , 0 ) , true , false ) ; this . camera . fieldOfView = 60 ; this . camera . clearColor = new Vector4 ( 0.7 , 0.8 , 0.9 , 0 ) ; this . camera . nearPlane = 0.01 ; this . camera . addComponent ( CameraMoveScript ) ; this . loadUI ( ) ; } private loadUI ( ) { Laya . loader . load ( [ "res/threeDimen/ui/button.png" ] , Handler . create ( this , async function ( ) { this . changeActionButton = Laya . stage . addChild ( new Button ( "res/threeDimen/ui/button.png" , "正常模式" ) ) ; this . changeActionButton . size ( 160 , 40 ) ; ( this . changeActionButton as Button ) . active = await WebXRExperienceHelper . supportXR ( "immersive-vr" ) ; this . changeActionButton . labelBold = true ; this . changeActionButton . labelSize = 30 ; this . changeActionButton . sizeGrid = "4,4,4,4" ; this . changeActionButton . scale ( Browser . pixelRatio , Browser . pixelRatio ) ; this . changeActionButton . pos ( Laya . stage . width / 2 - this . changeActionButton . width * Browser . pixelRatio / 2 , Laya . stage . height - 100 * Browser . pixelRatio ) ; this . changeActionButton . on ( Event . CLICK , this , this . stypeFun ) ; Promise . resolve ( true ) ; } ) ) ; } stypeFun ( ) { this . initXR ( ) ; } async initXR ( ) { let caInfo = new WebXRCameraInfo ( ) ; caInfo . depthFar = this . camera . farPlane ; caInfo . depthNear = this . camera . nearPlane ; let webXRSessionManager = await WebXRExperienceHelper . enterXRAsync ( "immersive-vr" , "local" , caInfo ) ; let webXRCameraManager = WebXRExperienceHelper . setWebXRCamera ( this . camera , webXRSessionManager ) ; let WebXRInput = WebXRExperienceHelper . setWebXRInput ( webXRSessionManager , webXRCameraManager ) ; this . bindMeshRender ( WebXRInput ) ; } bindMeshRender ( webXRInput ) { let rightControl = Laya . loader . getRes ( "res/OculusController/controller.gltf" ) as Sprite3D ; let leftControl = Laya . loader . getRes ( "res/OculusController/controller-left.gltf" ) as Sprite3D ; let pixelright = new PixelLineSprite3D ( 20 , "right" ) ; let pixelleft = new PixelLineSprite3D ( 20 , "left" ) ; this . scene . addChild ( rightControl ) ; this . scene . addChild ( leftControl ) ; this . scene . addChild ( pixelright ) ; this . scene . addChild ( pixelleft ) ; webXRInput . bindMeshNode ( leftControl , WebXRInput . HANDNESS_LEFT ) ; webXRInput . bindMeshNode ( rightControl , WebXRInput . HANDNESS_RIGHT ) ; webXRInput . bindRayNode ( pixelleft , WebXRInput . HANDNESS_LEFT ) ; webXRInput . bindRayNode ( pixelright , WebXRInput . HANDNESS_RIGHT ) ; webXRInput . getController ( WebXRInput . HANDNESS_RIGHT ) . on ( WebXRInput . EVENT_FRAMEUPDATA_WEBXRINPUT , this , this . getRightInput ) ; webXRInput . getController ( WebXRInput . HANDNESS_LEFT ) . on ( WebXRInput . EVENT_FRAMEUPDATA_WEBXRINPUT , this , this . getLeftInput ) ; /**
         * 0	扳机
         * 1	侧扳机
         * 3 	摇杆按下
         * 4	X、A键
         * 5	Y、B键
         */ let leftXRInput = webXRInput . getController ( WebXRInput . HANDNESS_LEFT ) ; leftXRInput . addButtonEvent ( 0 , ButtonGamepad . EVENT_TOUCH_OUT , this , this . LeftbuttonEvent0 ) ; leftXRInput . addButtonEvent ( 1 , ButtonGamepad . EVENT_TOUCH_STAY , this , this . LeftbuttonEvent1 ) ; leftXRInput . addButtonEvent ( 1 , ButtonGamepad . EVENT_TOUCH_OUT , this , this . LeftbuttonEvent1_1 ) ; leftXRInput . addButtonEvent ( 3 , ButtonGamepad . EVENT_TOUCH_OUT , this , this . LeftbuttonEvent3 ) ; leftXRInput . addButtonEvent ( 4 , ButtonGamepad . EVENT_TOUCH_ENTER , this , this . LeftbuttonEvent4 ) ; leftXRInput . addButtonEvent ( 5 , ButtonGamepad . EVENT_TOUCH_OUT , this , this . LeftbuttonEvent5 ) ; leftXRInput . addAxisEvent ( 1 , AxiGamepad . EVENT_OUTPUT , this , this . LeftAxisEvent ) ; let rightXRInput = webXRInput . getController ( WebXRInput . HANDNESS_RIGHT ) ; rightXRInput . addButtonEvent ( 0 , ButtonGamepad . EVENT_PRESS_ENTER , this , this . RightbuttonEvent0 ) ; rightXRInput . addButtonEvent ( 0 , ButtonGamepad . EVENT_PRESS_VALUE , this , this . rightTriggerOn ) ; rightXRInput . addButtonEvent ( 1 , ButtonGamepad . EVENT_PRESS_STAY , this , this . RightbuttonEvent1 ) ; rightXRInput . addButtonEvent ( 1 , ButtonGamepad . EVENT_PRESS_OUT , this , this . RightbuttonEvent1_1 ) ; rightXRInput . addButtonEvent ( 3 , ButtonGamepad . EVENT_PRESS_OUT , this , this . RightbuttonEvent3 ) ; rightXRInput . addButtonEvent ( 4 , ButtonGamepad . EVENT_PRESS_ENTER , this , this . RightbuttonEvent4 ) ; rightXRInput . addButtonEvent ( 5 , ButtonGamepad . EVENT_PRESS_OUT , this , this . RightbuttonEvent5 ) ; rightXRInput . addAxisEvent ( 1 , AxiGamepad . EVENT_OUTPUT , this , this . RightAxisEvent ) ; } getRightInput ( rightInput ) { var directionMod = Math . sqrt ( Math . pow ( rightInput . ray . direction . x , 2 ) + Math . pow ( rightInput . ray . direction . y , 2 ) + Math . pow ( rightInput . ray . direction . z , 2 ) ) ; var endPos = new Vector3 ( rightInput . ray . origin . x + Vector3 . dot ( rightInput . ray . direction , new Vector3 ( 1 , 0 , 0 ) ) / directionMod * this . rightTargetDistance , rightInput . ray . origin . y + Vector3 . dot ( rightInput . ray . direction , new Vector3 ( 0 , 1 , 0 ) ) / directionMod * this . rightTargetDistance , rightInput . ray . origin . z + Vector3 . dot ( rightInput . ray . direction , new Vector3 ( 0 , 0 , 1 ) ) / directionMod * this . rightTargetDistance ) ; var hitRes = new HitResult ( ) ; this . scene . physicsSimulation . rayCast ( rightInput . ray , hitRes ) ; if ( hitRes . succeeded ) { if ( ! this . isRightSelectTarget ) { this . rightTarget = hitRes . collider . owner as Sprite3D ; } } if ( this . isRightSelectTarget && this . rightTarget ) { this . rightTarget . transform . position = endPos ; this . rightTarget . transform . rotate ( new Vector3 ( 0 , 15 * this . rotateStrength , 0 ) , false , false ) ; } } getLeftInput ( leftInput ) { var directionMod = Math . sqrt ( Math . pow ( leftInput . ray . direction . x , 2 ) + Math . pow ( leftInput . ray . direction . y , 2 ) + Math . pow ( leftInput . ray . direction . z , 2 ) ) ; var endPos = new Vector3 ( leftInput . ray . origin . x + Vector3 . dot ( leftInput . ray . direction , new Vector3 ( 1 , 0 , 0 ) ) / directionMod * this . leftTargetDistance , leftInput . ray . origin . y + Vector3 . dot ( leftInput . ray . direction , new Vector3 ( 0 , 1 , 0 ) ) / directionMod * this . leftTargetDistance , leftInput . ray . origin . z + Vector3 . dot ( leftInput . ray . direction , new Vector3 ( 0 , 0 , 1 ) ) / directionMod * this . leftTargetDistance ) ; var hitRes = new HitResult ( ) ; this . scene . physicsSimulation . rayCast ( leftInput . ray , hitRes ) ; if ( hitRes . succeeded ) { if ( ! this . isLeftSelectTarget ) { this . leftTarget = hitRes . collider . owner as Sprite3D ; } } if ( this . isLeftSelectTarget && this . leftTarget ) { this . leftTarget . transform . position = endPos ; this . leftTarget . transform . rotate ( new Vector3 ( 0 , 15 * this . rotateStrength , 0 ) , false , false ) ; } } LeftbuttonEvent0 ( ) { console . log ( "left trigger" ) ; this . rotateStrength = 0.1 ; } LeftbuttonEvent1 ( ) { console . log ( "left side trigger" ) ; this . isLeftSelectTarget = true ; } LeftbuttonEvent1_1 ( ) { this . isLeftSelectTarget = false ; } LeftbuttonEvent3 ( ) { console . log ( "left stickPress" ) ; } LeftbuttonEvent4 ( ) { console . log ( "left key X" ) ; this . leftTargetDistance -= 0.5 ; } LeftbuttonEvent5 ( ) { console . log ( "left key Y" ) ; this . leftTargetDistance += 0.5 ; } leftTriggerOn ( value ) { this . rotateStrength = value ; } LeftAxisEvent ( value ) { console . log ( "left Axis MOUSE_EVENT" , value ) ; if ( this . leftTarget ) { this . leftTarget . transform . localRotationEulerX += value . y ; this . leftTarget . transform . localRotationEulerY += value . x ; } } RightbuttonEvent0 ( ) { console . log ( "right trigger" ) ; } RightbuttonEvent1 ( ) { console . log ( "right side trigger" ) ; this . isRightSelectTarget = true ; } RightbuttonEvent1_1 ( ) { console . log ( "right side trigger" ) ; this . isRightSelectTarget = false ; } RightbuttonEvent3 ( ) { console . log ( "right stickPress" ) ; this . rightTarget = this . scene . getChildByName ( "Cube" ) as Sprite3D ; } RightbuttonEvent4 ( ) { console . log ( "right key X" ) ; this . rightTargetDistance -= 0.5 ; } RightbuttonEvent5 ( ) { console . log ( "right key Y" ) ; this . rightTargetDistance += 0.5 ; } rightTriggerOn ( value ) { this . rotateStrength = value ; } RightAxisEvent ( value ) { if ( this . rightTarget ) { this . rightTarget . transform . localRotationEulerX += value . y ; this . rightTarget . transform . localRotationEulerY += value . x ; } } }