OculusVR: Add basic camera positioning

empirephoenix-patch-1
Campbell Suter 7 years ago
parent 8a3336704a
commit 601ba1cfda
No known key found for this signature in database
GPG Key ID: 754A66CCF3F73C0F
  1. 8
      jme3-vr/src/main/java/com/jme3/app/VRAppState.java
  2. 29
      jme3-vr/src/main/java/com/jme3/input/vr/OculusVR.java
  3. 83
      jme3-vr/src/main/java/com/jme3/util/VRViewManagerOculus.java

@ -399,14 +399,14 @@ public class VRAppState extends AbstractAppState {
//FIXME: check if this code is necessary.
// Updates scene and gui states.
Iterator<Spatial> spatialIter = application.getViewPort().getScenes().iterator();
Iterator<Spatial> spatialIter = getLeftViewPort().getScenes().iterator();
Spatial spatial = null;
while(spatialIter.hasNext()){
spatial = spatialIter.next();
spatial.updateLogicalState(tpf);
spatial.updateGeometricState();
}
}
if( environment.isInVR() == false || environment.getVRGUIManager().getPositioningMode() == VRGUIPositioningMode.MANUAL ) {
// only update geometric state here if GUI is in manual mode, or not in VR
// it will get updated automatically in the viewmanager update otherwise
@ -419,7 +419,7 @@ public class VRAppState extends AbstractAppState {
}
// use the analog control on the first tracked controller to push around the mouse
environment.getVRMouseManager().updateAnalogAsMouse(0, null, null, null, tpf);
// environment.getVRMouseManager().updateAnalogAsMouse(0, null, null, null, tpf);
}
@Override

@ -87,6 +87,11 @@ public class OculusVR implements VRAPI {
*/
private final Matrix4f[] eyePoses = new Matrix4f[2];
/**
* The eye poses, as used during rendering.
*/
private final OVRPosef eyePosesPtr[] = new OVRPosef[2];
// The size of the texture drawn onto the HMD
private int textureW;
private int textureH;
@ -240,6 +245,22 @@ public class OculusVR implements VRAPI {
OVRTrackingState hmdState = OVRTrackingState.malloc();
ovr_GetTrackingState(session, ftiming, true, hmdState);
//get head pose
OVRPosef headPose = hmdState.HeadPose().ThePose();
hmdState.free();
//build view offsets struct
OVRPosef.Buffer hmdToEyeOffsets = OVRPosef.calloc(2);
hmdToEyeOffsets.put(0, eyeRenderDesc[ovrEye_Left].HmdToEyePose());
hmdToEyeOffsets.put(1, eyeRenderDesc[ovrEye_Right].HmdToEyePose());
//calculate eye poses
OVRPosef.Buffer outEyePoses = OVRPosef.create(2);
OVRUtil.ovr_CalcEyePoses(headPose, hmdToEyeOffsets, outEyePoses);
hmdToEyeOffsets.free();
eyePosesPtr[ovrEye_Left] = outEyePoses.get(0);
eyePosesPtr[ovrEye_Right] = outEyePoses.get(1);
// TODO
}
@ -559,6 +580,14 @@ public class OculusVR implements VRAPI {
public PointerBuffer getLayers() {
return layers;
}
public OVRLayerEyeFov getLayer0() {
return layer0;
}
public OVRPosef[] getEyePosesPtr() {
return eyePosesPtr;
}
}
/* vim: set ts=4 softtabstop=0 sw=4 expandtab: */

@ -35,7 +35,9 @@ import com.jme3.app.VREnvironment;
import com.jme3.input.vr.OculusVR;
import com.jme3.input.vr.VRAPI;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
@ -45,11 +47,8 @@ import java.nio.IntBuffer;
import java.util.Iterator;
import java.util.logging.Logger;
import org.lwjgl.PointerBuffer;
import org.lwjgl.ovr.*;
import static org.lwjgl.BufferUtils.*;
import static org.lwjgl.ovr.OVR.*;
import static org.lwjgl.ovr.OVRErrorCode.*;
@ -65,6 +64,13 @@ public class VRViewManagerOculus extends AbstractVRViewManager {
private final VREnvironment environment;
private final OculusVR hardware;
// Copied from OSVR
//final & temp values for camera calculations
private final Vector3f finalPosition = new Vector3f();
private final Quaternion finalRotation = new Quaternion();
private final Vector3f hmdPos = new Vector3f();
private final Quaternion hmdRot = new Quaternion();
public VRViewManagerOculus(VREnvironment environment) {
this.environment = environment;
@ -94,20 +100,83 @@ public class VRViewManagerOculus extends AbstractVRViewManager {
// TODO
hardware.updatePose();
// TODO deduplicate
if (environment != null) {
// grab the observer
Object obs = environment.getObserver();
Quaternion objRot;
Vector3f objPos;
if (obs instanceof Camera) {
objRot = ((Camera) obs).getRotation();
objPos = ((Camera) obs).getLocation();
} else {
objRot = ((Spatial) obs).getWorldRotation();
objPos = ((Spatial) obs).getWorldTranslation();
}
// grab the hardware handle
VRAPI dev = environment.getVRHardware();
if (dev != null) {
// update the HMD's position & orientation
dev.getPositionAndOrientation(hmdPos, hmdRot);
if (obs != null) {
// update hmdPos based on obs rotation
finalRotation.set(objRot);
finalRotation.mult(hmdPos, hmdPos);
finalRotation.multLocal(hmdRot);
}
finalizeCamera(dev.getHMDVectorPoseLeftEye(), objPos, leftCamera);
finalizeCamera(dev.getHMDVectorPoseRightEye(), objPos, rightCamera);
} else {
leftCamera.setFrame(objPos, objRot);
rightCamera.setFrame(objPos, objRot);
}
if (environment.hasTraditionalGUIOverlay()) {
// update the mouse?
environment.getVRMouseManager().update(tpf);
// update GUI position?
if (environment.getVRGUIManager().wantsReposition || environment.getVRGUIManager().getPositioningMode() != VRGUIPositioningMode.MANUAL) {
environment.getVRGUIManager().positionGuiNow(tpf);
environment.getVRGUIManager().updateGuiQuadGeometricState();
}
}
} else {
throw new IllegalStateException("This VR view manager is not attached to any VR environment.");
}
}
/**
* Place the camera within the scene.
*
* @param eyePos the eye position.
* @param obsPosition the observer position.
* @param cam the camera to place.
*/
private void finalizeCamera(Vector3f eyePos, Vector3f obsPosition, Camera cam) {
finalRotation.mult(eyePos, finalPosition);
finalPosition.addLocal(hmdPos);
if (obsPosition != null) {
finalPosition.addLocal(obsPosition);
}
finalPosition.y += getHeightAdjustment();
cam.setFrame(finalPosition, finalRotation);
}
@Override
public void render() {
for (int eye = 0; eye < 2; eye++) {
// TODO add eyePoses
// OVRPosef eyePose = eyePoses[eye];
// layer0.RenderPose(eye, eyePose);
// TODO do we need this? Don't we set the camera positions ourselves?
OVRPosef eyePose = hardware.getEyePosesPtr()[eye];
hardware.getLayer0().RenderPose(eye, eyePose);
IntBuffer currentIndexB = BufferUtils.createIntBuffer(1);
ovr_GetTextureSwapChainCurrentIndex(session(), hardware.getChain(), currentIndexB);
int index = currentIndexB.get();
(eye == 0 ? leftViewPort : rightViewPort).setOutputFrameBuffer(hardware.getFramebuffers()[index]);
(eye == ovrEye_Left ? leftViewPort : rightViewPort).setOutputFrameBuffer(hardware.getFramebuffers()[index]);
}
// Now the game will render into the buffers given to us by LibOVR

Loading…
Cancel
Save