forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			250 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			250 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
|  | package kha.js.vr; | ||
|  | 
 | ||
|  | import js.Syntax; | ||
|  | import js.lib.Float32Array; | ||
|  | import kha.vr.Pose; | ||
|  | import kha.vr.PoseState; | ||
|  | import kha.vr.SensorState; | ||
|  | import kha.vr.TimeWarpParms; | ||
|  | import kha.math.FastMatrix4; | ||
|  | import kha.math.Vector3; | ||
|  | import kha.math.Quaternion; | ||
|  | import kha.SystemImpl; | ||
|  | 
 | ||
|  | class VrInterface extends kha.vr.VrInterface { | ||
|  | 	var vrEnabled: Bool = false; | ||
|  | 
 | ||
|  | 	var vrDisplay: Dynamic; | ||
|  | 	var frameData: Dynamic; | ||
|  | 
 | ||
|  | 	var leftProjectionMatrix: FastMatrix4 = FastMatrix4.identity(); | ||
|  | 	var rightProjectionMatrix: FastMatrix4 = FastMatrix4.identity(); | ||
|  | 	var leftViewMatrix: FastMatrix4 = FastMatrix4.identity(); | ||
|  | 	var rightViewMatrix: FastMatrix4 = FastMatrix4.identity(); | ||
|  | 
 | ||
|  | 	var width: Int = 0; | ||
|  | 	var height: Int = 0; | ||
|  | 	var vrWidth: Int = 0; | ||
|  | 	var vrHeight: Int = 0; | ||
|  | 
 | ||
|  | 	public function new() { | ||
|  | 		super(); | ||
|  | 		#if kha_webvr | ||
|  | 		var displayEnabled: Bool = Syntax.code("navigator.getVRDisplays"); | ||
|  | 		#else | ||
|  | 		var displayEnabled = false; | ||
|  | 		#end | ||
|  | 		if (displayEnabled) { | ||
|  | 			vrEnabled = true; | ||
|  | 			getVRDisplays(); | ||
|  | 			trace("Display enabled."); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function getVRDisplays() { | ||
|  | 		var vrDisplayInstance = Syntax.code("navigator.getVRDisplays()"); | ||
|  | 		vrDisplayInstance.then(function(displays) { | ||
|  | 			if (displays.length > 0) { | ||
|  | 				frameData = Syntax.code("new VRFrameData()"); | ||
|  | 				vrDisplay = Syntax.code("displays[0]"); | ||
|  | 				vrDisplay.depthNear = 0.1; | ||
|  | 				vrDisplay.depthFar = 1024.0; | ||
|  | 
 | ||
|  | 				var leftEye = vrDisplay.getEyeParameters("left"); | ||
|  | 				var rightEye = vrDisplay.getEyeParameters("right"); | ||
|  | 				width = SystemImpl.khanvas.width; | ||
|  | 				height = SystemImpl.khanvas.height; | ||
|  | 				vrWidth = Std.int(Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2); | ||
|  | 				vrHeight = Std.int(Math.max(leftEye.renderHeight, rightEye.renderHeight)); | ||
|  | 			} | ||
|  | 			else { | ||
|  | 				trace("There are no VR displays connected."); | ||
|  | 			} | ||
|  | 		}); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function onVRRequestPresent() { | ||
|  | 		try { | ||
|  | 			vrDisplay.requestPresent([{source: SystemImpl.khanvas}]).then(function() { | ||
|  | 				onResize(); | ||
|  | 				vrDisplay.requestAnimationFrame(onAnimationFrame); | ||
|  | 			}); | ||
|  | 		} | ||
|  | 		catch (err:Dynamic) { | ||
|  | 			trace("Failed to requestPresent."); | ||
|  | 			trace(err); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function onVRExitPresent() { | ||
|  | 		try { | ||
|  | 			vrDisplay.exitPresent([{source: SystemImpl.khanvas}]).then(function() { | ||
|  | 				onResize(); | ||
|  | 			}); | ||
|  | 		} | ||
|  | 		catch (err:Dynamic) { | ||
|  | 			trace("Failed to exitPresent."); | ||
|  | 			trace(err); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function onResetPose() { | ||
|  | 		try { | ||
|  | 			vrDisplay.resetPose(); | ||
|  | 		} | ||
|  | 		catch (err:Dynamic) { | ||
|  | 			trace("Failed to resetPose"); | ||
|  | 			trace(err); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function onAnimationFrame(timestamp: Float): Void { | ||
|  | 		if (vrDisplay != null && vrDisplay.isPresenting) { | ||
|  | 			vrDisplay.requestAnimationFrame(onAnimationFrame); | ||
|  | 
 | ||
|  | 			vrDisplay.getFrameData(frameData); | ||
|  | 
 | ||
|  | 			leftProjectionMatrix = createMatrixFromArray(untyped frameData.leftProjectionMatrix); | ||
|  | 			leftViewMatrix = createMatrixFromArray(untyped frameData.leftViewMatrix); | ||
|  | 
 | ||
|  | 			rightProjectionMatrix = createMatrixFromArray(untyped frameData.rightProjectionMatrix); | ||
|  | 			rightViewMatrix = createMatrixFromArray(untyped frameData.rightViewMatrix); | ||
|  | 
 | ||
|  | 			// Submit the newly rendered layer to be presented by the VRDisplay | ||
|  | 			vrDisplay.submitFrame(); | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function onResize() { | ||
|  | 		if (vrDisplay != null && vrDisplay.isPresenting) { | ||
|  | 			SystemImpl.khanvas.width = vrWidth; | ||
|  | 			SystemImpl.khanvas.height = vrHeight; | ||
|  | 		} | ||
|  | 		else { | ||
|  | 			SystemImpl.khanvas.width = width; | ||
|  | 			SystemImpl.khanvas.height = height; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function GetSensorState(): SensorState { | ||
|  | 		return GetPredictedSensorState(0.0); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function GetPredictedSensorState(time: Float): SensorState { | ||
|  | 		var result: SensorState = new SensorState(); | ||
|  | 
 | ||
|  | 		result.Predicted = new PoseState(); | ||
|  | 		result.Recorded = result.Predicted; | ||
|  | 
 | ||
|  | 		result.Predicted.AngularAcceleration = new Vector3(); | ||
|  | 		result.Predicted.AngularVelocity = new Vector3(); | ||
|  | 		result.Predicted.LinearAcceleration = new Vector3(); | ||
|  | 		result.Predicted.LinearVelocity = new Vector3(); | ||
|  | 		result.Predicted.TimeInSeconds = time; | ||
|  | 		result.Predicted.Pose = new Pose(); | ||
|  | 		result.Predicted.Pose.Orientation = new Quaternion(); | ||
|  | 		result.Predicted.Pose.Position = new Vector3(); | ||
|  | 
 | ||
|  | 		var mPose = frameData.pose; // predicted pose of the vrDisplay | ||
|  | 		if (mPose != null) { | ||
|  | 			result.Predicted.AngularVelocity = createVectorFromArray(untyped mPose.angularVelocity); | ||
|  | 			result.Predicted.AngularAcceleration = createVectorFromArray(untyped mPose.angularAcceleration); | ||
|  | 			result.Predicted.LinearVelocity = createVectorFromArray(untyped mPose.linearVelocity); | ||
|  | 			result.Predicted.LinearAcceleration = createVectorFromArray(untyped mPose.linearAcceleration); | ||
|  | 			result.Predicted.Pose.Orientation = createQuaternion(untyped mPose.orientation); | ||
|  | 			result.Predicted.Pose.Position = createVectorFromArray(untyped mPose.position); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return result; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Sends a black image to the warp swap thread | ||
|  | 	public override function WarpSwapBlack(): Void { | ||
|  | 		// TODO: Implement | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Sends the Oculus loading symbol to the warp swap thread | ||
|  | 	public override function WarpSwapLoadingIcon(): Void { | ||
|  | 		// TODO: Implement | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Sends the set of images to the warp swap thread | ||
|  | 	public override function WarpSwap(parms: TimeWarpParms): Void { | ||
|  | 		// TODO: Implement | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function IsPresenting(): Bool { | ||
|  | 		if (vrDisplay != null) | ||
|  | 			return vrDisplay.isPresenting; | ||
|  | 		return false; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function IsVrEnabled(): Bool { | ||
|  | 		return vrEnabled; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function GetTimeInSeconds(): Float { | ||
|  | 		return Scheduler.time(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function GetProjectionMatrix(eye: Int): FastMatrix4 { | ||
|  | 		if (eye == 0) { | ||
|  | 			return leftProjectionMatrix; | ||
|  | 		} | ||
|  | 		else { | ||
|  | 			return rightProjectionMatrix; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	public override function GetViewMatrix(eye: Int): FastMatrix4 { | ||
|  | 		if (eye == 0) { | ||
|  | 			return leftViewMatrix; | ||
|  | 		} | ||
|  | 		else { | ||
|  | 			return rightViewMatrix; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function createMatrixFromArray(array: Float32Array): FastMatrix4 { | ||
|  | 		var matrix: FastMatrix4 = FastMatrix4.identity(); | ||
|  | 		matrix._00 = array[0]; | ||
|  | 		matrix._01 = array[1]; | ||
|  | 		matrix._02 = array[2]; | ||
|  | 		matrix._03 = array[3]; | ||
|  | 		matrix._10 = array[4]; | ||
|  | 		matrix._11 = array[5]; | ||
|  | 		matrix._12 = array[6]; | ||
|  | 		matrix._13 = array[7]; | ||
|  | 		matrix._20 = array[8]; | ||
|  | 		matrix._21 = array[9]; | ||
|  | 		matrix._22 = array[10]; | ||
|  | 		matrix._23 = array[11]; | ||
|  | 		matrix._30 = array[12]; | ||
|  | 		matrix._31 = array[13]; | ||
|  | 		matrix._32 = array[14]; | ||
|  | 		matrix._33 = array[15]; | ||
|  | 		return matrix; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function createVectorFromArray(array: Float32Array): Vector3 { | ||
|  | 		var vector: Vector3 = new Vector3(0, 0, 0); | ||
|  | 		if (array != null) { | ||
|  | 			vector.x = array[0]; | ||
|  | 			vector.y = array[1]; | ||
|  | 			vector.z = array[2]; | ||
|  | 		} | ||
|  | 		return vector; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function createQuaternion(array: Float32Array): Quaternion { | ||
|  | 		var quaternion: Quaternion = new Quaternion(0, 0, 0, 0); | ||
|  | 		if (array != null) { | ||
|  | 			quaternion.x = array[0]; | ||
|  | 			quaternion.y = array[1]; | ||
|  | 			quaternion.z = array[2]; | ||
|  | 			quaternion.w = array[3]; | ||
|  | 		} | ||
|  | 		return quaternion; | ||
|  | 	} | ||
|  | } |