The wrapper itself is not dependent on jME in any way. To build the C++ part, i recommend following the "Minimal Oculus Application" tutorial in the developer section of the Oculus web site.
Let's start with the java side.
HMDInfo.java
This is pretty much a direct mapping of the HMD(Head Mounted Display) data, straight from the C++ code, hence the naming convention is not 100% java.
package oculusvr.input;
public class HMDInfo {
protected int HResolution;
protected int VResolution;
protected float HScreenSize;
protected float VScreenSize;
protected float VScreenCenter;
protected float EyeToScreenDistance;
protected float LensSeparationDistance;
protected float InterpupillaryDistance;
protected float[] DistortionK = new float[4];
protected int DesktopX;
protected int DesktopY;
protected String DisplayDeviceName = "";
protected long DisplayId = 0;
public int getHResolution() {
return HResolution;
}
public void setHResolution(int HResolution) {
this.HResolution = HResolution;
}
public int getVResolution() {
return VResolution;
}
public void setVResolution(int VResolution) {
this.VResolution = VResolution;
}
public float getHScreenSize() {
return HScreenSize;
}
public void setHScreenSize(float HScreenSize) {
this.HScreenSize = HScreenSize;
}
public float getVScreenCenter() {
return VScreenCenter;
}
public void setVScreenCenter(float VScreenCenter) {
this.VScreenCenter = VScreenCenter;
}
public float getEyeToScreenDistance() {
return EyeToScreenDistance;
}
public void setEyeToScreenDistance(float EyeToScreenDistance) {
this.EyeToScreenDistance = EyeToScreenDistance;
}
public float getLensSeperationDistance() {
return LensSeparationDistance;
}
public void setLensSeperationDistance(float LensSeperationDistance) {
this.LensSeparationDistance = LensSeperationDistance;
}
public float getInterpupillaryDistance() {
return InterpupillaryDistance;
}
public void setInterpupillaryDistance(float InterpupillaryDistance) {
this.InterpupillaryDistance = InterpupillaryDistance;
}
public float[] getDistortionK() {
return DistortionK;
}
public void setDistortionK(float[] DistortionK) {
this.DistortionK = DistortionK;
}
public int getDesktopX() {
return DesktopX;
}
public void setDesktopX(int DesktopX) {
this.DesktopX = DesktopX;
}
public int getDesktopY() {
return DesktopY;
}
public void setDesktopY(int DesktopY) {
this.DesktopY = DesktopY;
}
public String getDisplayDeviceName() {
return DisplayDeviceName;
}
public void setDisplayDeviceName(String DisplayDeviceName) {
this.DisplayDeviceName = DisplayDeviceName;
}
public long getDisplayId() {
return DisplayId;
}
public void setDisplayId(long DisplayId) {
this.DisplayId = DisplayId;
}
@Override
public String toString() {
return "HMDInfo [HResolution = " + HResolution +
", VResolution = " + VResolution +
", HScreenSize = " + HScreenSize +
", VScreenSize = " + VScreenSize +
", VScreenCenter = " + VScreenCenter +
", EyeToScreenDistance = " + EyeToScreenDistance +
", LensSeperationDistance = " + LensSeparationDistance +
", InterpupillaryDistance = " + InterpupillaryDistance +
", DistortionK = [" + DistortionK[0] + ", " + DistortionK[1] + ", " + DistortionK[2] + ", " + DistortionK[3] + "] " +
", DesktopX = " + DesktopX +
", DesktopY = " + DesktopY +
", DisplayDeviceName = " + DisplayDeviceName +
", DisplayId = " + DisplayId + "]";
}
}
OculusRift.java
The wrapper on the java side. Should be pretty self-explanatory with initialization and getter methods. One note, due to the overhead involved in calling native methods, I decided to grab all the rotation and acceleration data in one go (update()).
Please note that you might need to change the lib names depending on how you name your C++ project.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package oculusvr.input;
/**
*
* @author Rickard
*/
public class OculusRift {
static {
if(System.getProperty("sun.arch.data.model").equals("32")){
System.loadLibrary("OculusLib");
} else if (System.getProperty("sun.arch.data.model").equals("64")){
System.loadLibrary("OculusLib64");
}
}
public native boolean initialize();
/**
*
* @return array of [roll, pitch, yaw, acc x, acc y, acc z]
*/
public native float[] update();
// HMDInfo
public native int getHResolution();
public native int getVResolution();
public native float getHScreenSize();
public native float getVScreenSize();
public native float getVScreenCenter();
public native float getEyeToScreenDistance();
public native float getLensSeparationDistance();
public native float getInterpupillaryDistance();
public native float[] getDistortionK();
public native int getDesktopX();
public native int getDesktopY();
public native String getDisplayDeviceName();
public native long getDisplayId();
public native void destroy();
}
That's all the java that's needed. To the C++ code!
OculusRift.h
The much needed header file. Generated with javah:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class oculusvr_input_OculusRift */
#ifndef _Included_oculusvr_input_OculusRift
#define _Included_oculusvr_input_OculusRift
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: oculusvr_input_OculusRift
* Method: initialize
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_oculusvr_input_OculusRift_initialize
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: update
* Signature: ()[F
*/
JNIEXPORT jfloatArray JNICALL Java_oculusvr_input_OculusRift_update
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getHResolution
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getHResolution
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getVResolution
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getVResolution
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getHScreenSize
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getHScreenSize
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getVScreenSize
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getVScreenSize
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getVScreenCenter
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getVScreenCenter
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getEyeToScreenDistance
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getEyeToScreenDistance
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getLensSeparationDistance
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getLensSeparationDistance
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getInterpupillaryDistance
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getInterpupillaryDistance
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getDistortionK
* Signature: ()[F
*/
JNIEXPORT jfloatArray JNICALL Java_oculusvr_input_OculusRift_getDistortionK
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getDesktopX
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getDesktopX
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getDesktopY
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getDesktopY
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getDisplayDeviceName
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_oculusvr_input_OculusRift_getDisplayDeviceName
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: getDisplayId
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_oculusvr_input_OculusRift_getDisplayId
(JNIEnv *, jobject);
/*
* Class: oculusvr_input_OculusRift
* Method: destroy
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_oculusvr_input_OculusRift_destroy
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
OculusRift.cpp.
This is pretty much an adaptation of the "Minimal oculus application" found on the oculus site.
#include <jni.h>
#include <iostream>
#include <stdio.h>
#include "OVR.h"
#include "OculusRift.h"
using namespace OVR;
using namespace std;
Ptr<DeviceManager> pManager;
Ptr<HMDDevice> pHMD;
Ptr<SensorDevice> pSensor;
SensorFusion FusionResult;
HMDInfo Info;
bool InfoLoaded;
//#define STD_GRAV 9.81 // What SHOULD work with Rift, but off by 1000
#define STD_GRAV 0.00981 // This gives nice 1.00G on Z with Rift face down !!!
JNIEXPORT jboolean JNICALL Java_oculusvr_input_OculusRift_initialize
(JNIEnv *env, jobject thisObj) {
printf("Initializing Rift...\n");
System::Init();
bool initialized = false;
pManager = *DeviceManager::Create();
pHMD = *pManager->EnumerateDevices<HMDDevice>().CreateDevice();
if (pHMD){
printf("pHMD created\n");
InfoLoaded = pHMD->GetDeviceInfo(&Info);
pSensor = *pHMD->GetSensor();
}
else{
pSensor = *pManager->EnumerateDevices<SensorDevice>().CreateDevice();
}
if (pSensor)
{
printf("Attaching sensor\n");
FusionResult.AttachToSensor(pSensor);
initialized = true;
}
return initialized;
}
JNIEXPORT void JNICALL Java_oculusvr_input_OculusRift_destroyDevice
(JNIEnv *env, jobject thisObj) {
pSensor.Clear();
pHMD.Clear();
pManager.Clear();
System::Destroy();
return;
}
JNIEXPORT jfloatArray JNICALL Java_oculusvr_input_OculusRift_update
(JNIEnv *env, jobject thisObj) {
jfloat data[6];
Vector3f acc=FusionResult.GetAcceleration();
// yaw, pitch, roll
FusionResult.GetOrientation().GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&data[2], &data[1], &data[0]);
data[3] = acc.x / STD_GRAV;
data[4] = acc.y / STD_GRAV;
data[5] = acc.z / STD_GRAV;
jfloatArray result;
result = env->NewFloatArray(6);
if (result == NULL) {
return NULL; /* out of memory error thrown */
}
env->SetFloatArrayRegion(result, 0, 6, data);
return result;
}
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getHResolution
(JNIEnv *env, jobject thisObj) {
return Info.HResolution;
}
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getVResolution
(JNIEnv *env, jobject thisObj) {
return Info.VResolution;
}
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getHScreenSize
(JNIEnv *env, jobject thisObj) {
return Info.HScreenSize;
}
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getVScreenSize
(JNIEnv *env, jobject thisObj) {
return Info.VScreenSize;
}
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getVScreenCenter
(JNIEnv *env, jobject thisObj) {
return Info.VScreenCenter;
}
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getEyeToScreenDistance
(JNIEnv *env, jobject thisObj) {
return Info.EyeToScreenDistance;
}
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getLensSeparationDistance
(JNIEnv *env, jobject thisObj) {
return Info.LensSeparationDistance;
}
JNIEXPORT jfloat JNICALL Java_oculusvr_input_OculusRift_getInterpupillaryDistance
(JNIEnv *env, jobject thisObj) {
return Info.InterpupillaryDistance;
}
JNIEXPORT jfloatArray JNICALL Java_oculusvr_input_OculusRift_getDistortionK
(JNIEnv *env, jobject thisObj) {
jfloat* distortion = Info.DistortionK;
jfloatArray result;
result = env->NewFloatArray(6);
if (result == NULL) {
return NULL; /* out of memory error thrown */
}
env->SetFloatArrayRegion(result, 0, 6, distortion);
return result;
}
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getDesktopX
(JNIEnv *env, jobject thisObj) {
return Info.DesktopX;
}
JNIEXPORT jint JNICALL Java_oculusvr_input_OculusRift_getDesktopY
(JNIEnv *env, jobject thisObj) {
return Info.DesktopY;
}
JNIEXPORT jstring JNICALL Java_oculusvr_input_OculusRift_getDisplayDeviceName
(JNIEnv *env, jobject thisObj) {
char *name = Info.DisplayDeviceName;
jstring result = env->NewStringUTF(name);
return result;
}
JNIEXPORT jlong JNICALL Java_oculusvr_input_OculusRift_getDisplayId
(JNIEnv *env, jobject thisObj) {
return Info.DisplayId;
}
Edit: Update to the code. Formalized it a bit better