forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			386 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			386 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #if 0
 | |
| #include "VrInterface.h"
 | |
| 
 | |
| #ifdef VR_GEAR_VR
 | |
| 
 | |
| #include <kha/Image.h>
 | |
| #include <kha/math/Matrix4.h>
 | |
| #include <kha/math/Quaternion.h>
 | |
| #include <kha/math/Vector3.h>
 | |
| #include <kha/vr/Pose.h>
 | |
| #include <kha/vr/PoseState.h>
 | |
| #include <kha/vr/TimeWarpImage.h>
 | |
| 
 | |
| #include <GlTexture.h>
 | |
| #include <VrApi/VrApi.h>
 | |
| #include <VrApi/VrApi_Helpers.h>
 | |
| 
 | |
| #include <LibOvr/Src/Kernel/OVR_Math.h>
 | |
| 
 | |
| #include <Kore/log.h>
 | |
| 
 | |
| #endif
 | |
| 
 | |
| namespace Kore {
 | |
| //
 | |
| namespace VrInterface {
 | |
| //	// Is Set during Initialize
 | |
| #ifdef VR_GEAR_VR
 | |
| 	static ovrMobile* ovr;
 | |
| #endif
 | |
| 
 | |
| 	static JavaVM* cachedJVM;
 | |
| 
 | |
| 	static jobject instance;
 | |
| 
 | |
| 	static jclass koreActivity;
 | |
| 
 | |
| 	static float qx;
 | |
| 	static float qy;
 | |
| 	static float qz;
 | |
| 	static float qw;
 | |
| //
 | |
| void SetJVM(JavaVM* jvm) {
 | |
| 	cachedJVM = jvm;
 | |
| 
 | |
| 	// Grab the activity object
 | |
| 	JNIEnv* env;
 | |
| 	cachedJVM->AttachCurrentThread(&env, 0);
 | |
| 
 | |
| 	koreActivity = env->FindClass("tech/kode/kore/KoreActivity");
 | |
| 	koreActivity = (jclass) env->NewGlobalRef(koreActivity);
 | |
| 	jmethodID mid = env->GetStaticMethodID(koreActivity, "getInstance", "()Ltech/kode/kore/KoreActivity;");
 | |
| 
 | |
| 	instance = env->CallStaticObjectMethod(koreActivity, mid);
 | |
| 
 | |
| 	// Make sure that the garbage collector does not clean this up for us
 | |
| 	instance = env->NewGlobalRef(instance);
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| #ifdef VR_CARDBOARD
 | |
| 
 | |
| 
 | |
| 
 | |
| 	void DistortionBefore() {
 | |
| 		JNIEnv* env;
 | |
| 		cachedJVM->AttachCurrentThread(&env, 0);
 | |
| 
 | |
| 		jmethodID mid = env->GetMethodID(koreActivity, "DistortionBeforeFrame", "()V");
 | |
| 		env->CallObjectMethod(instance, mid);
 | |
| 	}
 | |
| 
 | |
| 	void DistortionAfter() {
 | |
| 		JNIEnv* env;
 | |
| 		cachedJVM->AttachCurrentThread(&env, 0);
 | |
| 
 | |
| 		jmethodID mid = env->GetMethodID(koreActivity, "DistortionAfterFrame", "()V");
 | |
| 		env->CallObjectMethod(instance, mid);
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	void DistortTexture(kha::Image_obj* image) {
 | |
| 		JNIEnv* env;
 | |
| 		cachedJVM->AttachCurrentThread(&env, 0);
 | |
| 
 | |
| 		jmethodID mid = env->GetMethodID(koreActivity, "DistortTexture", "(I)V");
 | |
| 		env->CallVoidMethod(instance, mid, image->renderTarget->_texture);
 | |
| 	}
 | |
| 
 | |
| 	void updateGaze(float x, float y, float z, float w) {
 | |
| 		qx = x;
 | |
| 		qy = y;
 | |
| 		qz = z;
 | |
| 		qw = w;
 | |
| 	}
 | |
| 
 | |
| 	template<typename T> T* CreateEmpty() {
 | |
| 
 | |
| 			return dynamic_cast<T*>(T::__CreateEmpty().mPtr);
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 	kha::math::Quaternion_obj* getGaze() {
 | |
| 		kha::math::Quaternion_obj* result = CreateEmpty<kha::math::Quaternion_obj>();
 | |
| 		result->__construct(qx, qy, qz, qw);
 | |
| 
 | |
| 		return result;
 | |
| 	}
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #ifdef VR_GEAR_VR
 | |
| 
 | |
| void Initialize() {
 | |
| 	ovrModeParms parms;
 | |
| 	parms.AsynchronousTimeWarp = true;
 | |
| 	parms.AllowPowerSave = true;
 | |
| 	parms.DistortionFileName = 0;
 | |
| 	parms.EnableImageServer = false;
 | |
| 	parms.SkipWindowFullscreenReset = true;
 | |
| 
 | |
| 
 | |
| 	// Grab the activity object
 | |
| 	JNIEnv* env;
 | |
| 	cachedJVM->AttachCurrentThread(&env, 0);
 | |
| 
 | |
| 
 | |
| 	jclass koreActivity = env->FindClass("tech/kode/kore/KoreActivity");
 | |
| 	jmethodID mid = env->GetStaticMethodID(koreActivity, "getInstance", "()Ltech/kode/kore/KoreActivity;");
 | |
| 
 | |
| 
 | |
| 	jobject instance = env->CallStaticObjectMethod(koreActivity, mid);
 | |
| 
 | |
| 	// Make sure that the garbage collector does not clean this up for us
 | |
| 	instance = env->NewGlobalRef(instance);
 | |
| 
 | |
| 	parms.ActivityObject = instance;
 | |
| 
 | |
| 	parms.GameThreadTid = 0;
 | |
| 	parms.CpuLevel = 2;
 | |
| 	parms.GpuLevel = 2;
 | |
| 
 | |
| 	ovrHmdInfo returnedHmdInfo;
 | |
| 
 | |
| 
 | |
| 
 | |
| 	ovr = ovr_EnterVrMode(parms, &returnedHmdInfo );
 | |
| }
 | |
| 
 | |
| void WarpSwapBlack() {
 | |
| 	// TODO: Not in the API anymore :-(
 | |
| 	//ovr_WarpSwapBlack(ovr);
 | |
| }
 | |
| 
 | |
| void WarpSwapLoadingIcon() {
 | |
| 	//ovr_WarpSwapLoadingIcon(ovr);
 | |
| }
 | |
| 
 | |
| 
 | |
| template<typename T> T* CreateEmpty() {
 | |
| 
 | |
| 	return dynamic_cast<T*>(T::__CreateEmpty().mPtr);
 | |
| }
 | |
| 
 | |
| 
 | |
| kha::math::Quaternion_obj* GetQuaternion(const ovrQuatf& q) {
 | |
| 	kha::math::Quaternion_obj* quaternion = CreateEmpty<kha::math::Quaternion_obj>();
 | |
| 	quaternion->__construct(0.0f, 0.0f, 0.0f, 0.0f);
 | |
| 
 | |
| 	quaternion->set_x(q.x);
 | |
| 	quaternion->set_y(q.y);
 | |
| 	quaternion->set_z(q.z);
 | |
| 	quaternion->set_w(q.w);
 | |
| 
 | |
| 	return quaternion;
 | |
| }
 | |
| 
 | |
| ovrQuatf GetQuaternion(kha::math::Quaternion_obj* quat) {
 | |
| 	ovrQuatf result;
 | |
| 	result.x = quat->get_x();
 | |
| 	result.y = quat->get_y();
 | |
| 	result.z = quat->get_z();
 | |
| 	result.w = quat->get_w();
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| ovrMatrix4f GetMatrix(kha::math::Matrix4_obj* mat) {
 | |
| 	ovrMatrix4f result;
 | |
| 	for (int x = 0; x < 4; x++) {
 | |
| 		for (int y = 0; y < 4; y++) {
 | |
| 			float f = mat->get(x, y);
 | |
| 			result.M[x][y] = f;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| kha::math::Vector3_obj* GetVector3(const ovrVector3f& v) {
 | |
| 	kha::math::Vector3_obj* vector = CreateEmpty<kha::math::Vector3_obj>();
 | |
| 	vector->x = v.x;
 | |
| 	vector->y = v.y;
 | |
| 	vector->z = v.z;
 | |
| 
 | |
| 	return vector;
 | |
| }
 | |
| 
 | |
| 
 | |
| ovrVector3f GetVector3(kha::math::Vector3_obj* v) {
 | |
| 	ovrVector3f result;
 | |
| 	result.x = v->x;
 | |
| 	result.y = v->y;
 | |
| 	result.z = v->z;
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| 
 | |
| kha::vr::Pose_obj* GetPose(const ovrPosef& nativePose) {
 | |
| 	kha::vr::Pose_obj* pose = CreateEmpty<kha::vr::Pose_obj>();
 | |
| 	pose->Position = GetVector3(nativePose.Position);
 | |
| 	pose->Orientation = GetQuaternion(nativePose.Orientation);
 | |
| 
 | |
| 	return pose;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| kha::vr::PoseState_obj* GetPoseState(const ovrPoseStatef& nativeState) {
 | |
| 	kha::vr::PoseState_obj* poseState = CreateEmpty<kha::vr::PoseState_obj>();
 | |
| 
 | |
| 	poseState->TimeInSeconds = nativeState.TimeInSeconds;
 | |
| 	poseState->AngularAcceleration = GetVector3(nativeState.AngularAcceleration);
 | |
| 	poseState->AngularVelocity = GetVector3(nativeState.AngularVelocity);
 | |
| 	poseState->LinearAcceleration = GetVector3(nativeState.LinearAcceleration);
 | |
| 	poseState->LinearVelocity = GetVector3(nativeState.LinearVelocity);
 | |
| 
 | |
| 	poseState->Pose = GetPose(nativeState.Pose);
 | |
| 
 | |
| 	return poseState;
 | |
| }
 | |
| 
 | |
| kha::vr::SensorState_obj* GetPredictedSensorState(const float time) {
 | |
| 	kha::vr::SensorState_obj* state = dynamic_cast<kha::vr::SensorState_obj*>(kha::vr::SensorState_obj::__CreateEmpty().mPtr);
 | |
| 
 | |
| 	ovrSensorState nativeState = ovr_GetPredictedSensorState(ovr, time);
 | |
| 
 | |
| 	state->Temperature = nativeState.Temperature;
 | |
| 	state->Status = nativeState.Status;
 | |
| 	state->Predicted = GetPoseState(nativeState.Predicted);
 | |
| 	state->Recorded = GetPoseState(nativeState.Recorded);
 | |
| 
 | |
| 	return state;
 | |
| }
 | |
| 
 | |
| 
 | |
| 	kha::vr::SensorState_obj* GetSensorState() {
 | |
| 		// 0.0 gets the last reading
 | |
| 		return GetPredictedSensorState(0.0f);
 | |
| 	}
 | |
| 
 | |
| 	ovrPosef GetPose(kha::vr::Pose_obj* pose) {
 | |
| 		ovrPosef result;
 | |
| 
 | |
| 		result.Orientation = GetQuaternion(pose->Orientation.mPtr);
 | |
| 		result.Position = GetVector3(pose->Position.mPtr);
 | |
| 
 | |
| 
 | |
| 		return result;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	ovrPoseStatef GetPoseState(kha::vr::PoseState_obj* poseState) {
 | |
| 		ovrPoseStatef result;
 | |
| 
 | |
| 		result.TimeInSeconds = poseState->TimeInSeconds;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 		result.AngularAcceleration = GetVector3(poseState->AngularAcceleration.mPtr);
 | |
| 		result.AngularVelocity = GetVector3(poseState->AngularVelocity.mPtr);
 | |
| 		result.LinearAcceleration = GetVector3(poseState->LinearAcceleration.mPtr);
 | |
| 		result.LinearVelocity = GetVector3(poseState->LinearVelocity.mPtr);
 | |
| 
 | |
| 		result.Pose = GetPose(poseState->Pose.mPtr);
 | |
| 
 | |
| 
 | |
| 		return result;
 | |
| 	}
 | |
| 
 | |
| 	ovrTimeWarpImage GetTimeWarpImage(kha::vr::TimeWarpImage_obj* image) {
 | |
| 		ovrTimeWarpImage result;
 | |
| 
 | |
| 		if (image == 0) {
 | |
| 			result.TexId = 0;
 | |
| 			return result;
 | |
| 		}
 | |
| 		if (image->Image->renderTarget != 0) {
 | |
| 			result.TexId = image->Image->renderTarget->_texture;
 | |
| 		} else {
 | |
| 			result.TexId = image->Image->texture->texture;
 | |
| 		}
 | |
| 		result.Pose = GetPoseState(image->Pose.mPtr);
 | |
| 		result.TexCoordsFromTanAngles = GetMatrix(image->TexCoordsFromTanAngles.mPtr);
 | |
| 		result.TexCoordsFromTanAngles = //TanAngleMatrixFromProjection(&result.TexCoordsFromTanAngles);
 | |
| 			TanAngleMatrixFromFov(90.0f);
 | |
| 
 | |
| 		return result;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	bool AreDifferent(ovrMatrix4f& lhs, ovrMatrix4f& rhs) {
 | |
| 		for (int x = 0; x < 4; x++) {
 | |
| 			for (int y = 0; y < 4; y++) {
 | |
| 
 | |
| 				if (Kore::abs(lhs.M[x][y] - rhs.M[x][y]) > 0.1f) return true;
 | |
| 			}
 | |
| 		}
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	void WarpSwap(kha::vr::TimeWarpParms_obj* parms) {
 | |
| 
 | |
| 
 | |
| 		ovrTimeWarpParms nativeParms = InitTimeWarpParms();
 | |
| 
 | |
| 		const double predictedTime = ovr_GetPredictedDisplayTime( ovr, 1, 1 );
 | |
| 		const ovrSensorState state = ovr_GetPredictedSensorState( ovr, predictedTime );
 | |
| 
 | |
| 		ovrTimeWarpImage leftImage = GetTimeWarpImage(parms->LeftImage.mPtr);
 | |
| 		ovrTimeWarpImage rightImage = GetTimeWarpImage(parms->RightImage.mPtr);
 | |
| 		ovrTimeWarpImage leftOverlay = GetTimeWarpImage(parms->LeftOverlay.mPtr);
 | |
| 		ovrTimeWarpImage rightOverlay = GetTimeWarpImage(parms->RightOverlay.mPtr);
 | |
| 		leftImage.Pose = state.Predicted;
 | |
| 		leftOverlay.TexId = 0;
 | |
| 		rightOverlay.TexId = 0;
 | |
| 
 | |
| 
 | |
| 		//nativeParms->WarpProgram = WP_SIMPLE;
 | |
| 
 | |
| 		nativeParms.Images[0][0] = leftImage;
 | |
| 		nativeParms.Images[0][1] = leftOverlay;
 | |
| 		nativeParms.Images[1][0] = rightImage;
 | |
| 		nativeParms.Images[1][1] = rightOverlay;
 | |
| 
 | |
| 		// nativeParms->WarpProgram = WP_OVERLAY_PLANE;
 | |
| 
 | |
| 		/*ovrMatrix4f comparison = OVR::Matrix4f::Translation(1.0f, 2.0f, 3.0f);
 | |
| 
 | |
| 		if (AreDifferent(comparison, nativeParms->Images[0][0].TexCoordsFromTanAngles)) {
 | |
| 			Kore::log(Kore::Info, "Matrices are different!");
 | |
| 		} else {
 | |
| 			Kore::log(Kore::Info, "Matrices are identical");
 | |
| 		} */
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 		//ovrTimeWarpParms testParms = InitTimeWarpParms( WARP_INIT_LOADING_ICON);
 | |
| 
 | |
| 
 | |
| 		ovr_WarpSwap(ovr, &nativeParms);
 | |
| 
 | |
| 
 | |
| 		// TODO: What about memory - who deletes What?
 | |
| 
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	double GetTimeInSeconds() {
 | |
| 		return ovr_GetTimeInSeconds();
 | |
| 
 | |
| 	}
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 
 | |
| }
 | |
| //
 | |
| }
 | |
| #endif
 |