forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			250 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Haxe
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Haxe
		
	
	
		
			Executable File
		
	
	
	
	
| 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;
 | |
| 	}
 | |
| }
 |