Oculus Rift Support

Well, this ‘simulator’ has option to switch resolutions up to 4k, I doubt that consumer version will have better resolution than that.

I know that this is not giving the feeling of Oculus. I was just interested if it shows the artifacts of the display in real fashion - I have read people complaining a lot about ‘screen door’ effect on DK1 and I wonder if it is anything similar to thing shown in simulator.

@abies said: Can anybody with Rift DK1 confirm how 'realistic' this simulator is? http://vr.mkeblx.net/oculus-sim/

I have four points in which the DK1 experience doesn’t really align with what you’re trying to show.

First up, visible persistence is much, much lower than what you’re simulating. The smearing visible on the DK1 feels like it’s about half what you’re presenting.

The “screen door” effect is both more pronounced and less visible on the real device. The lines are much darker, but the gap width vs pixel size is smaller on the actual device if that makes sense. What you have there is probably an appropriate compromise, but I figure that it’s worth noting.

The pixel ratio on your page is dependent on browser window size. I ended up with crazy tall simulated pixels.

The Rift’s technique of increasing the effective resolution by using lenses to decrease the pixel density around the periphery is a significant aspect (one that many people don’t seem to consider). 60 - 70% of the visible area is noticeably blurred. You’re expected to be staring straight ahead whilst wearing the rift.

It’s a neat idea though!

On topic, I’m planning to poke around with this. I suspect that Oculus getting acquired has probably taken a toll on people’s motivation (it definitely hurt mine), but I’m curious to see what state Rift support is in and what I can get done with jME as I see this as being of benefit to VR support in jME in general :slight_smile:

Will post back with anything that I manage to get done.

Just a note - it is not my simulator, I found it on the net.

@abies said: Just a note - it is not my simulator, I found it on the net.

Oh, ha ha. Sorry :smiley:

Howdy,

Anyone know if there is an API to detect head shake? It would be great to be able to detect such Motion :slight_smile:

I’m not sure if headshake with one pound of unbalanced gear attached to your head is a good idea for repeatable gesture. Repetitive stress injury in the neck is going to be less fun than in wrist…

Seems that Oculus has released new version of API. From one side it is simplier (smaller surface, C-based), so hopefully Swig should be able to generate nice wrapper? On the other hand, they made image correction more fancy now - it is not longer a simple shader, they want to either do image flipping/transmission to GPU themselves (probably no-go for many cases) or provide a uv-mesh which should be used for rendering final image.

I just pre-ordered the development kit 2, so I am very interested in getting jMonkeyEngine up to speed on the Oculus Rift. I’m developing on Linux, so the first thing I will want to do is get Linux support back (looks like just the Windows natives are in the jar). I hope to get to this ASAP, but any help will be appreciated.

OK, so I believe I built a shared library from the object files, made with the Oculus SDK 2.5c source for Linux64. I also added code in the OculusRiftReader.java to load the shared library. However, when it ties to load, I get this error:

[java]SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.UnsatisfiedLinkError: /home/phr00t/jmonkeyengine-oculus-rift-read-only/libovr64.so: /home/phr00t/jmonkeyengine-oculus-rift-read-only/libovr64.so: undefined symbol: _ZTVN10__cxxabiv117__class_type_infoE
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1965)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1890)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1880)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1088)
at oculusvr.input.OculusRiftReader.<clinit>(OculusRiftReader.java:71)…[/java]

Trying to make the shared library another way (straight from the libovr.a file from the SDK) causes this error:

[java]phr00t@phr00tlaptop:~/OculusSDK/LibOVR/Lib/Linux/Release/x86_64$ g++ -std=c++98 -g -O1 -fpic -shared -o libovr64.so -Wl,–whole-archive ./libovr.a
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS): In function __libc_csu_init': (.text+0xd): undefined reference to __init_array_end’
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS): relocation R_X86_64_PC32 against undefined hidden symbol `__init_array_end’ can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
[/java]

I’m not sure if my shared library is broken, incomplete, or there is some other problem… any suggestions? @rickard? :-/

@phr00t

Glad that you’re showing interest in fixing the multi platform issues!
The first error might have to do with how you supply the lib. Is it included in the project (and oculuslib.jar)?
The second one is new to me, i’m afraid.

Thank you for the response, @rickard!

I did put my shared library inside the oculuslib.jar file and it is being extracted OK. I think the problem lies in my shared library… How did you obtain / generate a shared Linux library when it seems the Oculus SDK only provides a static one?

I do notice my shared library ends up being about half the size of the static library…

Update: got past the first error. When creating the shared library, I had to specify -lstdc++, like:

gcc -shared -o libovr.so *.o -lstdc++

Now I get this error:

[java]SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.UnsatisfiedLinkError: oculusvr.input.OculusRift.initialize()Z
at oculusvr.input.OculusRift.initialize(Native Method)
at oculusvr.input.OculusRiftReader.initialize(OculusRiftReader.java:90)
at oculusvr.TestStereoCams.simpleInitApp(TestStereoCams.java:46)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:745)[/java]

If you run OculusRiftReader.java, does it work properly?
In that case, I think you have encountered the same issue as me (and several others). I’ve spent a considerable amount of time trying to fix this, but I’m unsure what the problem is.
It seems it will work when the lib is loaded from within a static context of the application using it, but not otherwise.
A suggestion is it might have to do with how jme loads libs, but I don’t think so. I’ve been using a JNI based lib for the Razer Hydra without any similar problems.
I don’t know if it the libovr’s causing problems, but at least it should not be my Visual Studio project setup if you get the same problems with the linux libs
A third option is there’s something wrong with the C++ code, more specifically in the initialization.

I can’t get OculusRiftReader.java to work. The exception you see is coming from trying to run it. Does it run for you? How do you load a static library – I thought it had to be shared?

This is the symbol table for the shared object I created, searching for anything to do with “initialize”:

[java]phr00t@phr00tlaptop:~/OculusSDK/LibOVR/Obj/Linux/Release/x86_64$ nm libovr64.so | grep Initialize
0000000000046060 W _ZN3OVR13HIDDeviceImplINS_12SensorDeviceEE10InitializeEPNS_10DeviceBaseE
0000000000035ee0 W _ZN3OVR13HIDDeviceImplINS_17LatencyTestDeviceEE10InitializeEPNS_10DeviceBaseE
0000000000045640 T _ZN3OVR16SensorDeviceImpl10InitializeEPNS_10DeviceBaseE
000000000002edf0 T _ZN3OVR17DeviceManagerImpl10InitializeEPNS_10DeviceBaseE
00000000000349e0 T _ZN3OVR21LatencyTestDeviceImpl10InitializeEPNS_10DeviceBaseE
0000000000038170 T _ZN3OVR5Linux13DeviceManager10InitializeEPNS_10DeviceBaseE
00000000000387a0 T _ZN3OVR5Linux16HIDDeviceManager10InitializeEv
0000000000039050 T _ZN3OVR5Linux9HIDDevice13HIDInitializeERKNS_6StringE
000000000003a150 T _ZN3OVR5Linux9HMDDevice10InitializeEPNS_10DeviceBaseE
0000000000049c00 T _ZN3OVR6System13IsInitializedEv
00000000000460f0 W _ZThn16_N3OVR13HIDDeviceImplINS_12SensorDeviceEE10InitializeEPNS_10DeviceBaseE
0000000000035f70 W _ZThn16_N3OVR13HIDDeviceImplINS_17LatencyTestDeviceEE10InitializeEPNS_10DeviceBaseE
00000000000456e0 T _ZThn16_N3OVR16SensorDeviceImpl10InitializeEPNS_10DeviceBaseE
0000000000034a80 T _ZThn16_N3OVR21LatencyTestDeviceImpl10InitializeEPNS_10DeviceBaseE
000000000002ee50 T _ZThn8_N3OVR17DeviceManagerImpl10InitializeEPNS_10DeviceBaseE
0000000000038270 T _ZThn8_N3OVR5Linux13DeviceManager10InitializeEPNS_10DeviceBaseE
000000000003a1c0 T _ZThn8_N3OVR5Linux9HMDDevice10InitializeEPNS_10DeviceBaseE
phr00t@phr00tlaptop:~/OculusSDK/LibOVR/Obj/Linux/Release/x86_64$ nm libovr64.so | grep initialize
00000000000386f0 T _ZN3OVR5Linux16HIDDeviceManager17initializeManagerEv
000000000004cd00 T _ZN3OVR5Timer21initializeTimerSystemEv
[/java]

I don’t see a simple “initialize” function… even if I ignore all the _Zxxx stuff at the start… are we sure we are using the correct initialize method for the Oculus here? This is the search of the header source files:

[java]phr00t@phr00tlaptop:~/OculusSDK/LibOVR/Src$ grep “initialize” *.h
OVR_Device.h: // Obtains the currently used profile name. This is initialized to the default
OVR_DeviceHandle.h: // Resets the device handle to uninitialized state.
OVR_LatencyTestImpl.h: bool initializeRead();
OVR_Linux_HIDDevice.h: bool initializeManager();
OVR_OSX_HIDDevice.h: bool initializeManager();
OVR_Win32_HIDDevice.h: bool initializeRead();[/java]

I don’t think there is any initialize() function anywhere… then it would make sense for the UnsatisfiedLinkError when trying to call that function. I’m out for most of today, but we should look for another way to initialize the device using the Linux SDK’s sample & source code(and see what other functions have changed).
<p>

EDIT: WWWWWAaaaaaaaaaiiiitttttttttttt I’m trying to load the OculusSDK libraries, when I should be just loading your code, correct? I don’t need to link with LibOVR at all…?
<p>

EDIT 2: Trying to build your code for Linux. First thing I had to do was change conio.h to curses.h… now getting a bunch of errors:

[java]oculusvr_input_OculusRift.cpp:14:2: error: ‘auto_ptr’ in namespace ‘std’ does not name a type
std::auto_ptr<SensorFusion> pFusionResult;
^
oculusvr_input_OculusRift.cpp: In function ‘jboolean Java_oculusvr_input_OculusRift_initialize(JNIEnv*, jobject)’:
oculusvr_input_OculusRift.cpp:24:4: error: ‘pFusionResult’ was not declared in this scope
pFusionResult.reset(new SensorFusion);
^
oculusvr_input_OculusRift.cpp: In function ‘void Java_oculusvr_input_OculusRift_destroy(JNIEnv*, jobject)’:
oculusvr_input_OculusRift.cpp:53:6: error: ‘pFusionResult’ was not declared in this scope
pFusionResult.reset();
^
oculusvr_input_OculusRift.cpp: In function ‘_jfloatArray* Java_oculusvr_input_OculusRift_update(JNIEnv*, jobject)’:
oculusvr_input_OculusRift.cpp:62:17: error: ‘pFusionResult’ was not declared in this scope
Vector3f acc=pFusionResult->GetAcceleration();


[/java]

Right, my code should contain all the links to the libovr. If you manage to build it, it should have all you need.

I’m not that well-versed with c++, so I can’t help you with the imports. I’ll see if I have some time tonight to look into it, or what I used when I tried to build it for linux, but I can’t promise anything. I hope there’s a way to at least have the c++ code platform agnostic.

The “_Z stuff” is mangled C++ names. (C++ compilers mangle Foo.getX() into a different name than Bar.getX() so that both functions can be called from C.)
http://demangler.com gave me this:
[java]phr00t@phr00tlaptop:~/OculusSDK/LibOVR/Obj/Linux/Release/x86_64$ nm libovr64.so | grep Initialize
0000000000046060 W OVR::HIDDeviceImpl<OVR::SensorDevice>::Initialize(OVR::DeviceBase*)
0000000000035ee0 W OVR::HIDDeviceImpl<OVR::LatencyTestDevice>::Initialize(OVR::DeviceBase*)
0000000000045640 T OVR::SensorDeviceImpl::Initialize(OVR::DeviceBase*)
000000000002edf0 T OVR::DeviceManagerImpl::Initialize(OVR::DeviceBase*)
00000000000349e0 T OVR::LatencyTestDeviceImpl::Initialize(OVR::DeviceBase*)
0000000000038170 T OVR::Linux::DeviceManager::Initialize(OVR::DeviceBase*)
00000000000387a0 T OVR::Linux::HIDDeviceManager::Initialize()
0000000000039050 T OVR::Linux::HIDDevice::HIDInitialize(OVR::String const&)
000000000003a150 T OVR::Linux::HMDDevice::Initialize(OVR::DeviceBase*)
0000000000049c00 T OVR::System::IsInitialized()
00000000000460f0 W non-virtual thunk to OVR::HIDDeviceImpl<OVR::SensorDevice>::Initialize(OVR::DeviceBase*)
0000000000035f70 W non-virtual thunk to OVR::HIDDeviceImpl<OVR::LatencyTestDevice>::Initialize(OVR::DeviceBase*)
00000000000456e0 T non-virtual thunk to OVR::SensorDeviceImpl::Initialize(OVR::DeviceBase*)
0000000000034a80 T non-virtual thunk to OVR::LatencyTestDeviceImpl::Initialize(OVR::DeviceBase*)
000000000002ee50 T non-virtual thunk to OVR::DeviceManagerImpl::Initialize(OVR::DeviceBase*)
0000000000038270 T non-virtual thunk to OVR::Linux::DeviceManager::Initialize(OVR::DeviceBase*)
000000000003a1c0 T non-virtual thunk to OVR::Linux::HMDDevice::Initialize(OVR::DeviceBase*)
phr00t@phr00tlaptop:~/OculusSDK/LibOVR/Obj/Linux/Release/x86_64$ nm libovr64.so | grep initialize
00000000000386f0 T OVR::Linux::HIDDeviceManager::initializeManager()
000000000004cd00 T OVR::timer::initializeTimerSystem()[/java]

I’m not sure what the non-virtual thunk stuff is - seems to have to do with stuff defined in include files (probably “declarations”, which are different from “definitions” in C++).

BTW you can use “grep -i” if to search for both Initialize and initialize.

I checked the code, the std::auto_ptr is a fix in the last update I made for something in the libovr (which i don’t remember). One thing you could try is to replace it with the normal Ptr.

It looks like your code doesn’t need either conio.h or curses.h, which are both platform depended includes. I just commented them both out. I also replaced those first errors with Ptr, and that worked. However, I get these errors:

[java]oculusvr_input_OculusRift.cpp: In function ‘jboolean Java_oculusvr_input_OculusRift_initialize(JNIEnv*, jobject)’:
oculusvr_input_OculusRift.cpp:25:18: error: ‘class OVR::Ptr<OVR::SensorFusion>’ has no member named ‘reset’
pFusionResult.reset(new SensorFusion);
^
In file included from /home/phr00t/OculusSDK/LibOVR/Include/…/Src/Kernel/OVR_Math.h:36:0,
from /home/phr00t/OculusSDK/LibOVR/Include/OVR.h:31,
from oculusvr_input_OculusRift.cpp:7:
/home/phr00t/OculusSDK/LibOVR/Include/…/Src/Kernel/OVR_RefCount.h: In instantiation of ‘OVR::Ptr<C>::~Ptr() [with C = OVR::SensorFusion]’:
oculusvr_input_OculusRift.cpp:15:20: required from here
/home/phr00t/OculusSDK/LibOVR/Include/…/Src/Kernel/OVR_RefCount.h:368:22: error: ‘class OVR::SensorFusion’ has no member named ‘Release’
if (pObject) pObject->Release();
^
[/java]

I comment out calls to .reset (in your code) & Release() (in the OculusSDK), just to make some progress, and it compiles. I create a shared library by running this script:

[java]g++ -c -fpic oculusvr_input_OculusRift.cpp -I/usr/lib/jvm/java-7-oracle/include/ -I/usr/lib/jvm/java-7-oracle/include/linux/ -I/home/phr00t/OculusSDK/LibOVR/Include/
g++ -shared -o libovr64.so *.o -lstdc++ -L. -lovr -ludev -lpthread -lX11 -lXinerama
ls -al libovr64.so
[/java]

“-lovr” is the static library provided by OculusSDK for Linux 64-bit (I had it in the local directory, hence the “-L.”).

I put the libovr64.so into the oculuslib.jar file (under linux/native), and I don’t get any exceptions when the library tries to load! However, I get these errors which probably have something to do with me not having an Oculus Rift:

[java]Oculus Rift could not be initialized
May 04, 2014 5:06:28 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:28 PM com.jme3.scene.plugins.ogre.MaterialLoader readPassStatement
WARNING: Unsupported pass directive: depth_write
May 04, 2014 5:06:28 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:28 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:28 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:28 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:29 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:29 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:29 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:29 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:29 PM com.jme3.scene.plugins.ogre.MaterialLoader readPassStatement
WARNING: Unsupported pass directive: depth_write
May 04, 2014 5:06:29 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op
May 04, 2014 5:06:29 PM com.jme3.scene.plugins.ogre.MaterialLoader readTextureUnitStatement
WARNING: Unsupported texture_unit directive: colour_op

A fatal error has been detected by the Java Runtime Environment:

SIGSEGV (0xb) at pc=0x00007f84d42fd950, pid=4558, tid=140208708314880

JRE version: Java™ SE Runtime Environment (7.0_55-b13) (build 1.7.0_55-b13)

Java VM: Java HotSpot™ 64-Bit Server VM (24.55-b03 mixed mode linux-amd64 compressed oops)

Problematic frame:

C [libovr64.so+0x29950] OVR::MessageHandler::GetHandlerLock() const+0x0

Failed to write core dump. Core dumps have been disabled. To enable core dumping, try “ulimit -c unlimited” before starting Java again

An error report file with more information is saved as:

/home/phr00t/jmonkeyengine-oculus-rift-read-only/hs_err_pid4558.log

If you would like to submit a bug report, please visit:

http://bugreport.sun.com/bugreport/crash.jsp

The crash happened outside the Java Virtual Machine in native code.

See problematic frame for where to report the bug.

Initializing Rift…
No HMD, creating sensorFailed to init sensor[/java]

Here is the libovr64.so file I created:

Can you make any progress with this information & library, @rickard? I’ll continue to do whatever I can to make this work, but I may be limited by not having an Oculus Rift :S

The last stacktrace is because the hardware can’t be found, so you’re in the ballpark.

I’m wondering about the first one, though. Are you using the latest SDK? Because I haven’t checked that out yet, might be that they’ve changed the API somewhat. I have it on my list to build for the latest version asap.

I’m not using the preview SDK – there isn’t a linux version available yet. v0.2.5c Linux 64 was the version I was using.

In the Oculus SDK, in OVR_SensorFusion.h, I see this:

[java] // Resets the current orientation.
void Reset();
[/java]

… but when trying to use the capital R version, I still get this:

[java]oculusvr_input_OculusRift.cpp: In function ‘jboolean Java_oculusvr_input_OculusRift_initialize(JNIEnv*, jobject)’:
oculusvr_input_OculusRift.cpp:26:18: error: ‘class OVR::Ptr<OVR::SensorFusion>’ has no member named ‘Reset’
pFusionResult.Reset();
^
[/java]

Although, I’m not up on my C++ like I should be… since the class isn’t just “SensorFusion” but Ptr<OVR::SensorFusion>, which I’m not sure how that works or changes things.

The Oculus SDK problem is very odd, since there are very many references to pObject->Release(), but just that one on line 368 causes problems for me.

@phr00t said: Although, I'm not up on my C++ like I should be... since the class isn't just "SensorFusion" but Ptr<OVR::SensorFusion>, which I'm not sure how that works or changes things.

That OVR:: thing is just a namespace qualifier.
Namespaces are C++'s equivalent of package names.

Ptr<SensorFusion> is a template, which is C++'s way of doing generics. I read the error message as “you’re dealing with a Ptr here, which does not have a Reset() function”.
I suspect the correct code would be using pFusionResult->Reset() instead of pFusionResult.Reset().

1 Like