|
|
|
@ -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
|
|
|
|
|