OculusVR: Add basic camera positioning
This commit is contained in:
parent
8a3336704a
commit
601ba1cfda
@ -399,7 +399,7 @@ 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();
|
||||
@ -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…
x
Reference in New Issue
Block a user