Skip to main content
Inspiring
December 5, 2014

JOVR 0.4.4.0: Java/Maven bindings for 0.4.4

I've updated my Java bindings for SDK 0.4.4. The source code can be found on Github here. Example code can be found here.

Developers using Maven (or a Maven compatible tool like Gradle) can declare a dependency on the following artifact:


<dependency>
<groupId>org.saintandreas</groupId>
<artifactId>jovr</artifactId>
<version>0.4.4.0</version>
</dependency>


Known issues

  • Only light testing has been done.

    28 replies

    Up and Coming
    December 16, 2014
    I actually had a try with some built in matrix stuff I found in JOGL today, just for comparison, and now my scene is just a sliver of black and white up in the sky which no amount of translate or rotating seems to fix. So I'm doing something fundamentally wrong still.

    So with my current latest approach. I have no lookat, fustrum, or other 'legacy' viewport stuff. I only use the projections provided by the SDK. I apply the translate, and then the rotate, which internally seems to be doing to multiplications you mentioned.

    Is there a standard library in Java/maven for doing this matrix stuff, rather than relying on internal library classes. I really dont want to have to roll my own.

    I think my next step is to take this all the way back to direct mode, but it feels like a big step backwards when both libraries are so close to working for me. Especially since my next step after I have the '2.1' code running is to have a go at some modern OpenGL.

            public void display(GLAutoDrawable drawable) {
    // System.out.println("Display "+frameCount);
    hmd.beginFrameTiming(++frameCount);
    GL2 gl = drawable.getGL().getGL2();
    Posef eyePoses[] = hmd.getEyePoses(frameCount, eyeOffsets);
    for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) {
    int eye = hmd.EyeRenderOrder[eyeIndex];
    Posef pose = eyePoses[eye];
    poses[eye].Orientation = pose.Orientation;
    poses[eye].Position = pose.Position;

    gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, eyeDFB[eye].getId());
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

    //Projection
    {
    pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
    pmvMatrix.glLoadIdentity();
    //pmvMatrix.glLoadMatrixf(rawProjections[eye].M, 0);
    pmvMatrix.glLoadMatrixf(Hmd.getPerspectiveProjection(fovPorts[eye], 0.1f, 1000000f, true).M, 0);

    gl.glMatrixMode(GL2.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glLoadMatrixf(pmvMatrix.glGetPMatrixf());
    }

    //ModelView
    {
    pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
    pmvMatrix.glLoadIdentity();
    pmvMatrix.glTranslatef(poses[eye].Position.x*-1, poses[eye].Position.y*-1, poses[eye].Position.z*-1);
    pmvMatrix.glTranslatef(0.0f, eyeHeight, 0.0f);

    Quaternion q = new Quaternion(poses[eye].Orientation.x, poses[eye].Orientation.y, poses[eye].Orientation.z, poses[eye].Orientation.w);
    q.invert();
    pmvMatrix.glRotate(q);

    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();
    gl.glLoadMatrixf(pmvMatrix.glGetMvMatrixf());
    }

    //scene
    {
    // tiles on floor
    gl.glEnable(GL2.GL_TEXTURE_2D);
    gl.glBindTexture(GL2.GL_TEXTURE_2D, cheq.getId());
    gl.glTranslatef(0.0f, -eyeHeight, 0.0f);
    gl.glLoadMatrixf(pmvMatrix.glGetMatrixf());

    drawPlaneXZ(gl);
    gl.glTranslatef(0.0f, eyeHeight, 0.0f);
    gl.glLoadMatrixf(pmvMatrix.glGetMatrixf());
    gl.glDisable(GL2.GL_TEXTURE_2D);
    }

    }
    gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
    gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);
    gl.glDisable(GL2.GL_TEXTURE_2D);

    frames.incrementAndGet();
    hmd.endFrame(poses, eyeTextures);
    }
    DK2, MBP (mid 2010) OSX 10.10.3. Win7 - i5 4670K - GTX770. Java LWJGL 3 OpenGL Experiments: https://github.com/WhiteHexagon
    Up and Coming
    December 16, 2014
    "whitehexagon" wrote:

    Is there a standard library in Java/maven for doing this matrix stuff, rather than relying on internal library classes. I really dont want to have to roll my own.


    I don't know, but it really isn't that difficult to roll your own. And in my opinion it will really help you to understand what is going on. As a starting point, you only need the formula to convert a quaternion to a 4x4 matrix, 4x4 translation matrices, 4x4 scaling matrices, and matrix multiplication. Based on that you can define any possible transformation just as a multiplication of these building blocks.

    "whitehexagon" wrote:

    I think my next step is to take this all the way back to direct mode, but it feels like a big step backwards when both libraries are so close to working for me. Especially since my next step after I have the '2.1' code running is to have a go at some modern OpenGL.


    As far as I can see, you are already using immediate mode right now, aren't you? After all, you are not passing your matrices to a shader at all? Maybe you may want to take a look at my Scala example, which contains very simple approaches to the whole shaders + vertex buffers + basic 4x4 matrix math that is typical for modern OpenGL. Apart from Scala's operator syntax you can do exactly the same in Java...

    In the code example you have posted, I would say that the translation and rotation are again in the wrong order (but I do not know if the library right or left multiplies so...). Did you try:


    pmvMatrix.glRotate(q.invert());
    pmvMatrix.glTranslatef(-poses[eye].Position.x, -poses[eye].Position.y - eyeHeight, -poses[eye].Position.z);
    Up and Coming
    December 17, 2014
    Thanks for your patience @bluenote. First I want to get to the bottom of this before I move forwards.

    Yes I am using immediate mode. I meant I remove the matrix stuff and strip the code down to simple functions like: glFrustrum, glTranslate and glRotate.

    On the projection side that has shown me that my near value of 0.1f was causing an issue, and the 1.0f worked better. I also now understand that the internal getPerspectiveProjection is equivalent to glFrustrum. And appears to be identical for each eye.

    On the ModelView side I have tried extracting the euler angles:

                    rotationY = (float)Math.atan(array[1]/array[0]);    //heading = atan(m01/m00)
    rotationX = (float)Math.asin(-array[2]); //attitude = asin(-m02)
    rotationZ = (float)Math.atan(array[6]/array[10]); //bank = atan(m12/m22)

    gl.glRotatef((float)Math.toDegrees(rotationY), 0.0f, 1.0f, 0.0f);
    gl.glRotatef((float)Math.toDegrees(rotationX), 1.0f, 0.0f, 0.0f);
    gl.glRotatef((float)Math.toDegrees(rotationZ), 0.0f, 0.0f, 1.0f);

    gl.glColor3f(1.0f, 0.0f, 0.0f);
    new GLUT().glutWireSphere(160, 16, 16);
    {
    gl.glTranslatef(-poses[eye].Position.x, -poses[eye].Position.y - eyeHeight, -poses[eye].Position.z);


    Doing this gave the impressions that some of the rotations where around the wrong axis. For example rotationY is affected by yaw/bank on the rift.

    When I got something that seemed to be moving in the right direction, I noticed it is similar to the original feeling that I'm not 1.8m above a tiled floor when it rotates. So my next check is to ensure I have the above angles being calculated correctly. I noticed that the Oculus SDK has a method: GetEulerAngles but I cant find this exposed on the JOVR binding?
    DK2, MBP (mid 2010) OSX 10.10.3. Win7 - i5 4670K - GTX770. Java LWJGL 3 OpenGL Experiments: https://github.com/WhiteHexagon
    Up and Coming
    December 17, 2014
    The problem with Euler angles is that you will have issues with Gimbal lock. When using the Rift this means that you will lose a degree of freedom when you look in a certain direction, which is really annoying. To avoid that it is better (and easier!) to just use the quaternion that you get from the SDK and cast it to the corresponding rotation matrix (by this formula I've linked above).
    Up and Coming
    December 18, 2014
    Thanks. This temporary approach with the Euler angles is just so I can get back to something I understand easier, ie. glRotate commands. I used your scala code to get a better conversion on the Euler angles now, and eventually found the correct order of applying pitch, roll, yaw (not sure how I should have know that). The scene still feels wrong though, not at all like I'm in the center of a room looking down at the floor. So I'm wondering if this is now something to do with scale, or the way I'm trying to draw the floor. Maybe my matrix stuff was right all along, and it's just the scene that is wrong!? or my perception of vr scenes!? At least I learned some scala today :)

    https://github.com/WhiteHexagon/example-jovr-jogl-rift/blob/master/src/main/java/com/sunshineapps/riftexample/RiftClient0440NoMatirx.java
    DK2, MBP (mid 2010) OSX 10.10.3. Win7 - i5 4670K - GTX770. Java LWJGL 3 OpenGL Experiments: https://github.com/WhiteHexagon
    Up and Coming
    April 28, 2015
    Is jovr compatible with direct mode?
    jhericoAuthor
    Inspiring
    April 29, 2015
    It is. It's just communicating with the same runtime using the same C++ code as in the normal SDK, just wrapped in Java. The runtime and the device driver are what manage direct mode.

    The only caveat is that for direct mode to work you have to call ovrHmd_attachToWindow with a native window handle, which isn't always easy to get from java APIs.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Up and Coming
    June 18, 2015
    "jherico" wrote:
    It is. It's just communicating with the same runtime using the same C++ code as in the normal SDK, just wrapped in Java. The runtime and the device driver are what manage direct mode.

    The only caveat is that for direct mode to work you have to call ovrHmd_attachToWindow with a native window handle, which isn't always easy to get from java APIs.


    Trying to run your sample in direct mode I see it on the wrong monitor, my lcd instead the oculus, does this come from the native window handle?