From 33e6574387aa6eede9b2b5f2787b4b82db534102 Mon Sep 17 00:00:00 2001 From: Julien Seinturier Date: Mon, 13 Feb 2017 11:42:37 +0100 Subject: [PATCH 1/2] Deprecated VRApplication. Now VRAppState should be used. --- jme3-vr/src/main/java/com/jme3/app/VRApplication.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java index f4fffbb89..08325bafc 100644 --- a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java +++ b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java @@ -71,8 +71,11 @@ import org.lwjgl.system.Platform; /** * A JMonkey application dedicated to Virtual Reality. An application that use VR devices (HTC vive, ...) has to extends this one.
+ *

+ * This class is no more functional and is deprecated. Please use {@link VRAppState VRAppState} instead. * @author reden - phr00t - https://github.com/phr00t * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + * @deprecated use {@link VRAppState VRAppState} instead. */ public abstract class VRApplication implements Application, SystemListener { From 6cf1b57e002b20c11519c2af02783606c97c3998 Mon Sep 17 00:00:00 2001 From: Julien Seinturier Date: Wed, 15 Feb 2017 11:19:18 +0100 Subject: [PATCH 2/2] Added VREnvironment class that gather the system related VR objetcs. This VREnvironment is independent from the JMonkey stuff and enables to check and initialize VR specific capabilities before initializing VRAppState. The procedure is now to initialize a VR environment and, if the initialization is ok, to attach a VRAppstate to the main application. Some class has been refactored: - System classes are within the com.jme3.system package - VR related utility classes are in the package com.jme3.util. --- .../main/java/com/jme3/app/VRAppState.java | 552 ++++------ .../main/java/com/jme3/app/VRApplication.java | 32 +- .../main/java/com/jme3/app/VREnvironment.java | 485 +++++++++ .../src/main/java/com/jme3/input/vr/OSVR.java | 53 +- .../java/com/jme3/input/vr/OSVRInput.java | 47 +- .../main/java/com/jme3/input/vr/OpenVR.java | 37 +- .../java/com/jme3/input/vr/OpenVRInput.java | 191 ++-- .../main/java/com/jme3/input/vr/VRAPI.java | 13 +- .../java/com/jme3/input/vr/VRInputAPI.java | 7 - .../util => com/jme3/post}/FilterUtil.java | 2 +- .../util => com/jme3/scene}/CenterQuad.java | 2 +- .../jme3/shadow/AbstractShadowRendererVR.java | 8 + .../DirectionalLightShadowRendererVR.java | 8 - .../InstancedDirectionalShadowFilter.java | 41 +- .../com/jme3/system/lwjgl/LwjglWindowVR.java | 2 - .../osvrclientkit/OsvrClientKitLibrary.java | 2 +- .../OSVR_AccelerationReport.java | 2 +- .../OSVR_AccelerationState.java | 2 +- .../OSVR_AnalogReport.java | 2 +- .../OSVR_AngularAccelerationReport.java | 2 +- .../OSVR_AngularVelocityReport.java | 2 +- .../OSVR_ButtonReport.java | 2 +- .../OSVR_DirectionReport.java | 2 +- .../OSVR_EyeTracker2DReport.java | 2 +- .../OSVR_EyeTracker3DReport.java | 2 +- .../OSVR_EyeTracker3DState.java | 2 +- .../OSVR_EyeTrackerBlinkReport.java | 2 +- .../OSVR_IncrementalQuaternion.java | 2 +- .../OSVR_LinearAccelerationReport.java | 2 +- .../OSVR_LinearVelocityReport.java | 2 +- .../OSVR_Location2DReport.java | 2 +- .../OSVR_NaviPositionReport.java | 2 +- .../OSVR_NaviVelocityReport.java | 2 +- .../OSVR_OrientationReport.java | 2 +- .../osvrclientreporttypes/OSVR_Pose3.java | 2 +- .../OSVR_PoseReport.java | 2 +- .../OSVR_PositionReport.java | 2 +- .../OSVR_Quaternion.java | 2 +- .../osvrclientreporttypes/OSVR_Vec2.java | 2 +- .../osvrclientreporttypes/OSVR_Vec3.java | 2 +- .../OSVR_VelocityReport.java | 2 +- .../OSVR_VelocityState.java | 2 +- .../OsvrClientReportTypesLibrary.java | 2 +- .../osvr}/osvrdisplay/OsvrDisplayLibrary.java | 5 +- .../osvrinterface/OsvrInterfaceLibrary.java | 8 +- .../osvrmatrixconventions/OSVR_Pose3.java | 2 +- .../OSVR_Quaternion.java | 2 +- .../osvrmatrixconventions/OSVR_Vec3.java | 2 +- .../OsvrMatrixConventionsLibrary.java | 2 +- .../OSVR_ProjectionMatrix.java | 2 +- .../osvr}/osvrrendermanager/OSVR_RGB.java | 2 +- .../osvrrendermanager}/OSVR_RenderParams.java | 2 +- .../OSVR_ViewportDescription.java | 2 +- .../OsvrRenderManagerLibrary.java | 22 +- .../OSVR_GraphicsLibraryOpenGL.java | 6 +- .../OSVR_OpenGLContextParams.java | 2 +- .../OSVR_OpenGLToolkitFunctions.java | 2 +- .../OSVR_OpenResultsOpenGL.java | 2 +- .../OSVR_ProjectionMatrix.java | 2 +- .../osvrrendermanageropengl/OSVR_RGB.java | 2 +- .../OSVR_RenderBufferOpenGL.java | 2 +- .../OSVR_RenderInfoOpenGL.java | 4 +- .../OSVR_RenderParams.java | 2 +- .../OSVR_ViewportDescription.java | 2 +- .../OsvrRenderManagerOpenGLLibrary.java | 34 +- .../osvr}/osvrtimevalue/OSVR_TimeValue.java | 2 +- .../osvrtimevalue/OsvrTimeValueLibrary.java | 2 +- .../com/jme3/util/AbstractVRViewManager.java | 223 ++++ .../com/jme3/util/VRGUIPositioningMode.java | 15 + .../main/java/com/jme3/util/VRGuiManager.java | 474 +++++++++ .../java/com/jme3/util/VRMouseManager.java | 334 ++++++ .../java/{jmevr => com/jme3}/util/VRUtil.java | 7 +- .../java/com/jme3/util/VRViewManager.java | 156 +++ .../java/com/jme3/util/VRViewManagerOSVR.java | 957 ++++++++++++++++++ .../com/jme3/util/VRViewManagerOpenVR.java | 732 ++++++++++++++ .../src/main/java/jmevr/util/MeshUtil.java | 107 -- .../main/java/jmevr/util/VRGuiManager.java | 334 ------ .../main/java/jmevr/util/VRMouseManager.java | 234 ----- .../main/java/jmevr/util/VRViewManager.java | 863 ---------------- 79 files changed, 3872 insertions(+), 2215 deletions(-) create mode 100644 jme3-vr/src/main/java/com/jme3/app/VREnvironment.java rename jme3-vr/src/main/java/{jmevr/util => com/jme3/post}/FilterUtil.java (95%) rename jme3-vr/src/main/java/{jmevr/util => com/jme3/scene}/CenterQuad.java (99%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientkit/OsvrClientKitLibrary.java (99%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_AccelerationReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_AccelerationState.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_AnalogReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_AngularAccelerationReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_AngularVelocityReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_ButtonReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_DirectionReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_EyeTracker2DReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_EyeTracker3DReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_EyeTracker3DState.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_EyeTrackerBlinkReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_IncrementalQuaternion.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_LinearAccelerationReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_LinearVelocityReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_Location2DReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_NaviPositionReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_NaviVelocityReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_OrientationReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_Pose3.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_PoseReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_PositionReport.java (96%) rename jme3-vr/src/main/java/{osvrmatrixconventions => com/jme3/system/osvr/osvrclientreporttypes}/OSVR_Quaternion.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_Vec2.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_Vec3.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_VelocityReport.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OSVR_VelocityState.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrclientreporttypes/OsvrClientReportTypesLibrary.java (98%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrdisplay/OsvrDisplayLibrary.java (99%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrinterface/OsvrInterfaceLibrary.java (81%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrmatrixconventions/OSVR_Pose3.java (96%) rename jme3-vr/src/main/java/{osvrclientreporttypes => com/jme3/system/osvr/osvrmatrixconventions}/OSVR_Quaternion.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrmatrixconventions/OSVR_Vec3.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrmatrixconventions/OsvrMatrixConventionsLibrary.java (99%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanager/OSVR_ProjectionMatrix.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanager/OSVR_RGB.java (95%) rename jme3-vr/src/main/java/{osvrrendermanageropengl => com/jme3/system/osvr/osvrrendermanager}/OSVR_RenderParams.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanager/OSVR_ViewportDescription.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanager/OsvrRenderManagerLibrary.java (82%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_GraphicsLibraryOpenGL.java (81%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_OpenGLContextParams.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_OpenGLToolkitFunctions.java (98%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_OpenResultsOpenGL.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_ProjectionMatrix.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_RGB.java (95%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_RenderBufferOpenGL.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_RenderInfoOpenGL.java (94%) rename jme3-vr/src/main/java/{osvrrendermanager => com/jme3/system/osvr/osvrrendermanageropengl}/OSVR_RenderParams.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OSVR_ViewportDescription.java (97%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrrendermanageropengl/OsvrRenderManagerOpenGLLibrary.java (79%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrtimevalue/OSVR_TimeValue.java (96%) rename jme3-vr/src/main/java/{ => com/jme3/system/osvr}/osvrtimevalue/OsvrTimeValueLibrary.java (99%) create mode 100644 jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java create mode 100644 jme3-vr/src/main/java/com/jme3/util/VRGUIPositioningMode.java create mode 100644 jme3-vr/src/main/java/com/jme3/util/VRGuiManager.java create mode 100644 jme3-vr/src/main/java/com/jme3/util/VRMouseManager.java rename jme3-vr/src/main/java/{jmevr => com/jme3}/util/VRUtil.java (98%) create mode 100644 jme3-vr/src/main/java/com/jme3/util/VRViewManager.java create mode 100644 jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java create mode 100644 jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java delete mode 100644 jme3-vr/src/main/java/jmevr/util/MeshUtil.java delete mode 100644 jme3-vr/src/main/java/jmevr/util/VRGuiManager.java delete mode 100644 jme3-vr/src/main/java/jmevr/util/VRMouseManager.java delete mode 100644 jme3-vr/src/main/java/jmevr/util/VRViewManager.java diff --git a/jme3-vr/src/main/java/com/jme3/app/VRAppState.java b/jme3-vr/src/main/java/com/jme3/app/VRAppState.java index 1c91977f3..5b850c931 100644 --- a/jme3-vr/src/main/java/com/jme3/app/VRAppState.java +++ b/jme3-vr/src/main/java/com/jme3/app/VRAppState.java @@ -1,23 +1,53 @@ package com.jme3.app; - +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ import com.jme3.app.Application; import com.jme3.app.state.AbstractAppState; import com.jme3.app.state.AppStateManager; -import com.jme3.input.vr.OSVR; -import com.jme3.input.vr.OpenVR; import com.jme3.input.vr.VRAPI; import com.jme3.input.vr.VRInputAPI; import com.jme3.math.ColorRGBA; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.post.PreNormalCaching; -import com.jme3.renderer.Camera; import com.jme3.renderer.RenderManager; import com.jme3.renderer.ViewPort; import com.jme3.scene.Spatial; import com.jme3.system.AppSettings; -import com.jme3.system.jopenvr.JOpenVRLibrary; +import com.jme3.util.VRGUIPositioningMode; +import com.jme3.util.VRGuiManager; +import com.jme3.util.VRMouseManager; +import com.jme3.util.VRViewManager; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; @@ -30,11 +60,6 @@ import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; -import jmevr.util.VRGuiManager; -import jmevr.util.VRMouseManager; -import jmevr.util.VRViewManager; -import jmevr.util.VRGuiManager.POSITIONING_MODE; - /** * A JMonkey app state dedicated to Virtual Reality. * An application that want to use VR devices (HTC vive, ...) has to use this app state.
@@ -53,50 +78,20 @@ public class VRAppState extends AbstractAppState { private static final Logger logger = Logger.getLogger(VRAppState.class.getName()); - /** - * The underlying system VR API. By default set to {@link VRConstants#SETTING_VRAPI_OPENVR_VALUE}. - */ - public int vrBinding = VRConstants.SETTING_VRAPI_OPENVR_VALUE; - /** * Is the application has not to start within VR mode (default is false). */ public boolean DISABLE_VR = false; - private VRAPI VRhardware = null; - private VRGuiManager guiManager = null; - private VRMouseManager mouseManager = null; - private VRViewManager viewmanager = null; - - private String OS; - - private Camera dummyCam; - - private Spatial observer = null; - - private boolean VRSupportedOS; - private boolean forceVR = false;; - private boolean disableSwapBuffers = true; - private boolean disableVR = false; - private boolean seated; - private boolean nogui; - private boolean instanceVR = false; - private float defaultFOV = 108f; - private float defaultAspect = 1f; - - - + private float fFar = 1000f; private float fNear = 0.1f; private int xWin = 1920; private int yWin = 1080; private float resMult = 1f; - - private boolean useCompositor = true; - private boolean compositorOS; - + /* where is the headset pointing, after all rotations are combined? depends on observer rotation, if any @@ -107,32 +102,27 @@ public class VRAppState extends AbstractAppState { private AppStateManager stateManager = null; private AppSettings settings = null; + private VREnvironment environment = null; /** - * Create a new default VR app state. + * Create a new default VR app state that relies on the given {@link VREnvironment VR environment}. + * @param environment the {@link VREnvironment VR environment} that this app state is using. */ - public VRAppState() { - super(); + public VRAppState(VREnvironment environment) { + super(); - dummyCam = new Camera(); - - // Create the GUI manager. - guiManager = new VRGuiManager(); - - // Create a new view manager. - viewmanager = new VRViewManager(); - - // Create a new mouse manager. - mouseManager = new VRMouseManager(); + this.environment = environment; + this.setSettings(environment.getSettings()); } /** - * Create a new VR app state with given settings. + * Create a new VR app state with given settings. The app state relies on the the given {@link VREnvironment VR environment}. * @param settings the settings to use. + * @param environment the {@link VREnvironment VR environment} that this app state is using. */ - public VRAppState(AppSettings settings){ - this(); + public VRAppState(AppSettings settings, VREnvironment environment){ + this(environment); this.settings = settings; processSettings(settings); } @@ -152,7 +142,7 @@ public class VRAppState extends AbstractAppState { * @param renderManager the {@link RenderManager render manager}. */ public void simpleRender(RenderManager renderManager) { - PreNormalCaching.resetCache(isInVR()); + PreNormalCaching.resetCache(environment.isInVR()); } /** @@ -181,163 +171,18 @@ public class VRAppState extends AbstractAppState { */ public void setResolutionMultiplier(float val) { resMult = val; - if( viewmanager != null ){ - viewmanager.setResolutionMultiplier(resMult); + if( environment.getVRViewManager() != null ){ + environment.getVRViewManager().setResolutionMultiplier(resMult); } } - - /** - * Is the VR compositor is active. - * @return true if the VR compositor is active and false otherwise. - */ - public boolean compositorAllowed() { - return useCompositor && compositorOS; - } - - /** - * Get if the system currently support VR. - * @return true if the system currently support VR and false otherwise. - */ - public boolean isVRSupported() { - return VRSupportedOS; - } - - /** - * Get the {@link Camera camera} attached to this application state. - * If the VR mode is {@link #isInVR() active}, this method return a dummy camera, otherwise, - * this method return the camera of the attached application. - * @return the camera attached to this application state. - */ - public Camera getCamera() { - if( isInVR() && viewmanager != null && viewmanager.getLeftCamera() != null ) { - return dummyCam; - } - - return application.getCamera(); - } - - /** - * Can be used to change seated experience during runtime. - * @param isSeated true if designed for sitting, false for standing/roomscale - * @see #isSeatedExperience() - */ - public void setSeatedExperience(boolean isSeated) { - seated = isSeated; - if( VRhardware instanceof OpenVR ) { - if( VRhardware.getCompositor() == null ) return; - if( seated ) { - ((OpenVR)VRhardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated); - } else { - ((OpenVR)VRhardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding); - } - } - } - - /** - * Check if the application is configured as a seated experience. - * @return true if the application is configured as a seated experience and false otherwise. - * @see #setSeatedExperience(boolean) - */ - public boolean isSeatedExperience() { - return seated; - } - - /** - * Reset headset pose if seating experience. - */ - public void resetSeatedPose(){ - if( VRSupportedOS == false || isSeatedExperience() == false ) return; - VRhardware.reset(); - } - - /** - * Check if the rendering is instanced (see Geometry instancing). - * @return true if the rendering is instanced and false otherwise. - */ - public boolean isInstanceVRRendering() { - return instanceVR && isInVR(); - } - - /** - * Check if the VR mode is enabled. - * @return true if the VR mode is enabled and false otherwise. - */ - public boolean isInVR() { - return DISABLE_VR == false && (forceVR || VRSupportedOS && VRhardware != null && VRhardware.isInitialized()); - } - - /** - * Get the default Field Of View (FOV) value. - * @return the default Field Of View (FOV) value. - * @see #setDefaultFOV(float) - */ - public float getDefaultFOV() { - return defaultFOV; - } - - /** - * Set the default Field Of View (FOV) value. - * @param defaultFOV the default Field Of View (FOV) value. - * @see #getDefaultFOV() - */ - public void setDefaultFOV(float defaultFOV) { - this.defaultFOV = defaultFOV; - } - - /** - * Get the default aspect ratio. - * @return the default aspect ratio. - * @see #setDefaultAspect(float) - */ - public float getDefaultAspect() { - return defaultAspect; - } - - /** - * Set the default aspect ratio. - * @param defaultAspect the default aspect ratio. - * @see #getDefaultAspect() - */ - public void setDefaultAspect(float defaultAspect) { - this.defaultAspect = defaultAspect; - } + /** * Move filters from the main scene into the eye's. * This removes filters from the main scene. */ public void moveScreenProcessingToVR() { - if( isInVR() ) { - viewmanager.moveScreenProcessingToEyes(); - } - } - - /** - * Check if the application has a GUI overlay attached. - * @return true if the application has a GUI overlay attached and false otherwise. - */ - public boolean hasTraditionalGUIOverlay() { - return !nogui; - } - - /** - * Get the scene observer. If no observer has been set, this method return the application {@link #getCamera() camera}. - * @return the scene observer. - * @see #setObserver(Spatial) - */ - public Object getObserver() { - if( observer == null ) { - return getCamera(); - } - return observer; - } - - /** - * Set the scene observer. The VR headset will be linked to it. If no observer is set, the VR headset is linked to the the application {@link #getCamera() camera}. - * @param observer the scene observer. - */ - public void setObserver(Spatial observer) { - this.observer = observer; + environment.getVRViewManager().moveScreenProcessingToEyes(); } /** @@ -346,17 +191,20 @@ public class VRAppState extends AbstractAppState { * @see #getFinalObserverPosition() */ public Quaternion getFinalObserverRotation() { - if( viewmanager == null ) { - if( observer == null ) { - return getCamera().getRotation(); - } else return observer.getWorldRotation(); - } - if( observer == null ) { - tempq.set(dummyCam.getRotation()); + if( environment.getVRViewManager() == null ) { + if( environment.getObserver() == null ) { + return environment.getCamera().getRotation(); + } else { + return ((Spatial)environment.getObserver()).getWorldRotation(); + } + } + + if( environment.getObserver() == null ) { + tempq.set(environment.getDummyCamera().getRotation()); } else { - tempq.set(observer.getWorldRotation()); + tempq.set(((Spatial)environment.getObserver()).getWorldRotation()); } - return tempq.multLocal(VRhardware.getOrientation()); + return tempq.multLocal(environment.getVRHardware().getOrientation()); } /** @@ -365,50 +213,35 @@ public class VRAppState extends AbstractAppState { * @see #getFinalObserverRotation() */ public Vector3f getFinalObserverPosition() { - if( viewmanager == null ) { - if( observer == null ) { - return getCamera().getLocation(); - } else return observer.getWorldTranslation(); + if( environment.getVRViewManager() == null ) { + if( environment.getObserver() == null ) { + return environment.getCamera().getLocation(); + } else{ + return ((Spatial)environment.getObserver()).getWorldTranslation(); + } } - Vector3f pos = VRhardware.getPosition(); - if( observer == null ) { - dummyCam.getRotation().mult(pos, pos); - return pos.addLocal(dummyCam.getLocation()); + + Vector3f pos = environment.getVRHardware().getPosition(); + if( environment.getObserver() == null ) { + environment.getDummyCamera().getRotation().mult(pos, pos); + return pos.addLocal(environment.getDummyCamera().getLocation()); } else { - observer.getWorldRotation().mult(pos, pos); - return pos.addLocal(observer.getWorldTranslation()); + ((Spatial)environment.getObserver()).getWorldRotation().mult(pos, pos); + return pos.addLocal(((Spatial)environment.getObserver()).getWorldTranslation()); } } - /** - * Set the VR headset height from the ground. - * @param amount the VR headset height from the ground. - * @see #getVRHeightAdjustment() - */ - public void setVRHeightAdjustment(float amount) { - if( viewmanager != null ) viewmanager.setHeightAdjustment(amount); - } - - /** - * Get the VR headset height from the ground. - * @return the VR headset height from the ground. - * @see #setVRHeightAdjustment(float) - */ - public float getVRHeightAdjustment() { - if( viewmanager != null ){ - return viewmanager.getHeightAdjustment(); - } - return 0f; - } - /** * Get the VR headset left viewport. * @return the VR headset left viewport. * @see #getRightViewPort() */ public ViewPort getLeftViewPort() { - if( viewmanager == null ) return application.getViewPort(); - return viewmanager.getLeftViewport(); + if( environment.getVRViewManager() == null ){ + return application.getViewPort(); + } + + return environment.getVRViewManager().getLeftViewport(); } /** @@ -417,8 +250,10 @@ public class VRAppState extends AbstractAppState { * @see #getLeftViewPort() */ public ViewPort getRightViewPort() { - if( viewmanager == null ) return application.getViewPort(); - return viewmanager.getRightViewport(); + if( environment.getVRViewManager() == null ){ + return application.getViewPort(); + } + return environment.getVRViewManager().getRightViewport(); } /** @@ -426,11 +261,15 @@ public class VRAppState extends AbstractAppState { * @param clr the background color. */ public void setBackgroundColors(ColorRGBA clr) { - if( viewmanager == null ) { + if( environment.getVRViewManager() == null ) { application.getViewPort().setBackgroundColor(clr); - } else if( viewmanager.getLeftViewport() != null ) { - viewmanager.getLeftViewport().setBackgroundColor(clr); - if( viewmanager.getRightViewport() != null ) viewmanager.getRightViewport().setBackgroundColor(clr); + } else if( environment.getVRViewManager().getLeftViewport() != null ) { + + environment.getVRViewManager().getLeftViewport().setBackgroundColor(clr); + + if( environment.getVRViewManager().getRightViewport() != null ){ + environment.getVRViewManager().getRightViewport().setBackgroundColor(clr); + } } } @@ -452,12 +291,45 @@ public class VRAppState extends AbstractAppState { return stateManager; } + /** + * Get the scene observer. If no observer has been set, this method return the application {@link #getCamera() camera}. + * @return the scene observer. + * @see #setObserver(Spatial) + */ + public Object getObserver() { + return environment.getObserver(); + } + + /** + * Set the scene observer. The VR headset will be linked to it. If no observer is set, the VR headset is linked to the the application {@link #getCamera() camera}. + * @param observer the scene observer. + */ + public void setObserver(Spatial observer) { + environment.setObserver(observer); + } + + /** + * Check if the rendering is instanced (see Geometry instancing). + * @return true if the rendering is instanced and false otherwise. + */ + public boolean isInstanceRendering() { + return environment.isInstanceRendering(); + } + + /** + * Return the {@link VREnvironment VR environment} on which this app state relies. + * @return the {@link VREnvironment VR environment} on which this app state relies. + */ + public VREnvironment getVREnvironment(){ + return environment; + } + /** * Get the VR underlying hardware. * @return the VR underlying hardware. */ public VRAPI getVRHardware() { - return VRhardware; + return getVREnvironment().getVRHardware(); } /** @@ -465,11 +337,11 @@ public class VRAppState extends AbstractAppState { * @return the VR dedicated input. */ public VRInputAPI getVRinput() { - if( VRhardware == null ){ + if( getVREnvironment().getVRHardware() == null ){ return null; } - return VRhardware.getVRinput(); + return getVREnvironment().getVRHardware().getVRinput(); } /** @@ -477,23 +349,23 @@ public class VRAppState extends AbstractAppState { * @return the VR view manager. */ public VRViewManager getVRViewManager() { - return viewmanager; + return getVREnvironment().getVRViewManager(); } /** - * Get the GUI manager attached to this application. - * @return the GUI manager attached to this application. + * Get the GUI manager attached to this app state. + * @return the GUI manager attached to this app state. */ public VRGuiManager getVRGUIManager(){ - return guiManager; + return getVREnvironment().getVRGUIManager(); } /** - * Get the VR mouse manager attached to this application. + * Get the VR mouse manager attached to this app state. * @return the VR mouse manager attached to this application. */ public VRMouseManager getVRMouseManager(){ - return mouseManager; + return getVREnvironment().getVRMouseManager(); } /** @@ -519,10 +391,10 @@ public class VRAppState extends AbstractAppState { public void update(float tpf) { // update VR pose & cameras - if( viewmanager != null ) { - viewmanager.update(tpf); - } else if( observer != null ) { - getCamera().setFrame(observer.getWorldTranslation(), observer.getWorldRotation()); + if( environment.getVRViewManager() != null ) { + environment.getVRViewManager().update(tpf); + } else if( environment.getObserver() != null ) { + environment.getCamera().setFrame(((Spatial)environment.getObserver()).getWorldTranslation(), ((Spatial)environment.getObserver()).getWorldRotation()); } //FIXME: check if this code is necessary. @@ -535,7 +407,7 @@ public class VRAppState extends AbstractAppState { spatial.updateGeometricState(); } - if( isInVR() == false || guiManager.getPositioningMode() == POSITIONING_MODE.MANUAL ) { + 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 spatialIter = application.getGuiViewPort().getScenes().iterator(); @@ -546,17 +418,17 @@ public class VRAppState extends AbstractAppState { } } - // use the analog control on the first tracked controller to push around the mouse - getVRMouseManager().updateAnalogAsMouse(0, null, null, null, tpf); + environment.getVRMouseManager().updateAnalogAsMouse(0, null, null, null, tpf); } @Override public void postRender() { super.postRender(); - // update compositor? - if( viewmanager != null ) { - viewmanager.sendTextures(); + + // update compositor + if( environment.getVRViewManager() != null ) { + environment.getVRViewManager().postRender(); } } @@ -571,27 +443,21 @@ public class VRAppState extends AbstractAppState { // for late GUI placement for VR purposes Logger.getLogger("com.jme3").setLevel(Level.SEVERE); - // VR module attch - guiManager.attach(this, app); - viewmanager.attach(this, app); - mouseManager.attach(this, app); - app.getCamera().setFrustumFar(fFar); app.getCamera().setFrustumNear(fNear); - dummyCam = app.getCamera().clone(); - - if( isInVR() ) { + + if( environment.isInVR() ) { logger.config("VR mode enabled."); - if( VRhardware != null ) { - VRhardware.initVRCompositor(compositorAllowed()); + if( environment.getVRHardware() != null ) { + environment.getVRHardware().initVRCompositor(environment.compositorAllowed()); } else { logger.warning("No VR system found."); } - viewmanager.setResolutionMultiplier(resMult); + environment.getVRViewManager().setResolutionMultiplier(resMult); //inputManager.addMapping(RESET_HMD, new KeyTrigger(KeyInput.KEY_F9)); //setLostFocusBehavior(LostFocusBehavior.Disabled); } else { @@ -600,8 +466,8 @@ public class VRAppState extends AbstractAppState { //guiViewPort.attachScene(guiNode); } - if( viewmanager != null ) { - viewmanager.initialize(); + if( environment.getVRViewManager() != null ) { + environment.getVRViewManager().initialize(); } } @@ -615,34 +481,21 @@ public class VRAppState extends AbstractAppState { } else { logger.config("Using given settings."); } + + // Attach VR environment to the application + if (!environment.isInitialized()){ + environment.initialize(); + } - // we are going to use OpenVR now, not the Oculus Rift - // OpenVR does support the Rift - OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH); - VRSupportedOS = !OS.contains("nux") && System.getProperty("sun.arch.data.model").equalsIgnoreCase("64"); //for the moment, linux/unix causes crashes, 64-bit only - compositorOS = OS.contains("indows"); - - if( VRSupportedOS && disableVR == false ) { - if( vrBinding == VRConstants.SETTING_VRAPI_OSVR_VALUE ) { - VRhardware = new OSVR(this); - logger.config("Creating OSVR wrapper [SUCCESS]"); - } else if( vrBinding == VRConstants.SETTING_VRAPI_OPENVR_VALUE ) { - VRhardware = new OpenVR(this); - logger.config("Creating OpenVR wrapper [SUCCESS]"); - } else { - logger.config("Cannot create VR binding: "+vrBinding+" [FAILED]"); - } - - if( VRhardware.initialize() ) { - logger.config("VR native wrapper initialized [SUCCESS]"); - } else { - logger.warning("VR native wrapper initialized [FAILED]"); - } - } - + if (environment.isInitialized()){ + environment.atttach(this, stateManager.getApplication()); + } else { + logger.severe("Cannot attach VR environment to the VR app state as its not initialized."); + } + GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - if( isInVR() && !compositorAllowed() ) { + if( environment.isInVR() && !environment.compositorAllowed() ) { // "easy extended" mode // setup experimental JFrame on external device // first, find the VR device @@ -694,14 +547,14 @@ public class VRAppState extends AbstractAppState { logger.config("Cannot access to external screen."); } } else { - if (!isInVR()){ + if (!environment.isInVR()){ logger.config("Cannot switch to VR mode (VR disabled by user)."); - } else if (!compositorAllowed()){ + } else if (!environment.compositorAllowed()){ logger.warning("Cannot switch to VR mode (VR not supported)."); } } - if( !isInVR() ) { + if( !environment.isInVR() ) { //FIXME: Handling GLFW workaround on MacOS boolean macOs = false; @@ -742,10 +595,10 @@ public class VRAppState extends AbstractAppState { settings.setHeight(yWin); settings.setBitsPerPixel(32); settings.setFrameRate(0); - settings.setFrequency(VRhardware.getDisplayFrequency()); + settings.setFrequency(environment.getVRHardware().getDisplayFrequency()); settings.setFullscreen(false); settings.setVSync(false); // stop vsyncing on primary monitor! - settings.setSwapBuffers(disableSwapBuffers); + settings.setSwapBuffers(environment.isSwapBuffers()); } // Updating application settings @@ -756,11 +609,9 @@ public class VRAppState extends AbstractAppState { @Override public void cleanup() { - if( VRhardware != null ) { - VRhardware.destroy(); - VRhardware = null; + if( environment.getVRHardware() != null ) { + environment.getVRHardware().destroy(); } - disableVR = true; this.application = null; this.stateManager = null; @@ -777,67 +628,10 @@ public class VRAppState extends AbstractAppState { */ protected void processSettings(AppSettings settings){ if (settings != null){ - if (settings.get(VRConstants.SETTING_USE_COMPOSITOR) != null){ - useCompositor = settings.getBoolean(VRConstants.SETTING_USE_COMPOSITOR); - if( useCompositor == false ){ - disableSwapBuffers = false; - } - } - if (settings.get(VRConstants.SETTING_VR_FORCE) != null){ - forceVR = settings.getBoolean(VRConstants.SETTING_VR_FORCE); - } - - if (settings.get(VRConstants.SETTING_FLIP_EYES) != null){ - if( VRhardware != null ){ - VRhardware._setFlipEyes(settings.getBoolean(VRConstants.SETTING_FLIP_EYES)); - } - } - - if (settings.get(VRConstants.SETTING_GUI_OVERDRAW) != null){ - guiManager._enableGuiOverdraw(settings.getBoolean(VRConstants.SETTING_GUI_OVERDRAW)); - } - - if (settings.get(VRConstants.SETTING_GUI_CURVED_SURFACE) != null){ - guiManager._enableCurvedSuface(settings.getBoolean(VRConstants.SETTING_GUI_CURVED_SURFACE)); - } - - if (settings.get(VRConstants.SETTING_ENABLE_MIRROR_WINDOW) != null){ - if( useCompositor == false ) { - disableSwapBuffers = false; - } else { - disableSwapBuffers = !settings.getBoolean(VRConstants.SETTING_ENABLE_MIRROR_WINDOW); - } - } - if (settings.get(VRConstants.SETTING_DISABLE_VR) != null){ DISABLE_VR = settings.getBoolean(VRConstants.SETTING_DISABLE_VR); } - - if (settings.get(VRConstants.SETTING_SEATED_EXPERIENCE) != null){ - seated = settings.getBoolean(VRConstants.SETTING_SEATED_EXPERIENCE); - } - - if (settings.get(VRConstants.SETTING_NO_GUI) != null){ - nogui = settings.getBoolean(VRConstants.SETTING_NO_GUI); - } - - if (settings.get(VRConstants.SETTING_INSTANCE_RENDERING) != null){ - instanceVR = settings.getBoolean(VRConstants.SETTING_INSTANCE_RENDERING); - } - - if (settings.get(VRConstants.SETTING_DEFAULT_FOV) != null){ - defaultFOV = settings.getFloat(VRConstants.SETTING_DEFAULT_FOV); - } - - if (settings.get(VRConstants.SETTING_DEFAULT_ASPECT_RATIO) != null){ - defaultAspect = settings.getFloat(VRConstants.SETTING_DEFAULT_ASPECT_RATIO); - } - - if (settings.get(VRConstants.SETTING_VRAPI) != null){ - vrBinding = settings.getInteger(VRConstants.SETTING_VRAPI); - } - } } } \ No newline at end of file diff --git a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java index 08325bafc..698451248 100644 --- a/jme3-vr/src/main/java/com/jme3/app/VRApplication.java +++ b/jme3-vr/src/main/java/com/jme3/app/VRApplication.java @@ -45,10 +45,13 @@ import com.jme3.system.SystemListener; import com.jme3.system.Timer; import com.jme3.system.lwjgl.LwjglDisplayVR; import com.jme3.system.lwjgl.LwjglOffscreenBufferVR; +import com.jme3.util.VRGUIPositioningMode; +import com.jme3.util.VRGuiManager; +import com.jme3.util.VRMouseManager; +import com.jme3.util.VRViewManagerOpenVR; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; -import java.awt.HeadlessException; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -61,11 +64,6 @@ import java.util.concurrent.Future; import java.util.logging.Level; import java.util.logging.Logger; -import jmevr.util.VRViewManager; -import jmevr.util.VRGuiManager; -import jmevr.util.VRGuiManager.POSITIONING_MODE; -import jmevr.util.VRMouseManager; - import org.lwjgl.system.Platform; @@ -174,7 +172,7 @@ public abstract class VRApplication implements Application, SystemListener { private VRAPI VRhardware = null; private VRGuiManager guiManager = null; private VRMouseManager mouseManager = null; - private VRViewManager viewmanager = null; + private VRViewManagerOpenVR viewmanager = null; private String OS; @@ -258,13 +256,13 @@ public abstract class VRApplication implements Application, SystemListener { initStateManager(); // Create the GUI manager. - guiManager = new VRGuiManager(); + guiManager = new VRGuiManager(null); // Create a new view manager. - viewmanager = new VRViewManager(); + viewmanager = new VRViewManagerOpenVR(null); // Create a new mouse manager. - mouseManager = new VRMouseManager(); + mouseManager = new VRMouseManager(null); // we are going to use OpenVR now, not the Oculus Rift // OpenVR does support the Rift @@ -313,7 +311,7 @@ public abstract class VRApplication implements Application, SystemListener { * Get the VR view manager. * @return the VR view manager. */ - public VRViewManager getVRViewManager() { + public VRViewManagerOpenVR getVRViewManager() { return viewmanager; } @@ -844,10 +842,10 @@ public abstract class VRApplication implements Application, SystemListener { public void preconfigureVRApp(PreconfigParameter parm, boolean value) { switch( parm ) { case SET_GUI_OVERDRAW: - guiManager._enableGuiOverdraw(value); + guiManager.setGuiOverdraw(value); break; case SET_GUI_CURVED_SURFACE: - guiManager._enableCurvedSuface(value); + guiManager.setCurvedSurface(value); break; case FORCE_VR_MODE: forceVR = value; @@ -861,7 +859,7 @@ public abstract class VRApplication implements Application, SystemListener { break; case FLIP_EYES: if( VRhardware == null ) return; - VRhardware._setFlipEyes(value); + VRhardware.setFlipEyes(value); break; case INSTANCE_VR_RENDERING: instanceVR = value; @@ -1182,7 +1180,7 @@ public abstract class VRApplication implements Application, SystemListener { rootNode.updateGeometricState(); - if( isInVR() == false || guiManager.getPositioningMode() == POSITIONING_MODE.MANUAL ) { + if( isInVR() == false || guiManager.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 guiNode.updateGeometricState(); @@ -1194,7 +1192,7 @@ public abstract class VRApplication implements Application, SystemListener { // update compositor? if( viewmanager != null ) { - viewmanager.sendTextures(); + viewmanager.postRender(); } } @@ -1361,7 +1359,7 @@ public abstract class VRApplication implements Application, SystemListener { } //FIXME: WARNING !! - viewmanager = new VRViewManager(); + viewmanager = new VRViewManagerOpenVR(null); viewmanager.setResolutionMultiplier(resMult); inputManager.addMapping(RESET_HMD, new KeyTrigger(KeyInput.KEY_F9)); setLostFocusBehavior(LostFocusBehavior.Disabled); diff --git a/jme3-vr/src/main/java/com/jme3/app/VREnvironment.java b/jme3-vr/src/main/java/com/jme3/app/VREnvironment.java new file mode 100644 index 000000000..e9e6d0aac --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/app/VREnvironment.java @@ -0,0 +1,485 @@ +package com.jme3.app; + +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.app.state.AppState; +import com.jme3.input.vr.OSVR; +import com.jme3.input.vr.OpenVR; +import com.jme3.input.vr.VRAPI; +import com.jme3.input.vr.VRInputAPI; +import com.jme3.renderer.Camera; +import com.jme3.scene.Spatial; +import com.jme3.system.AppSettings; +import com.jme3.system.jopenvr.JOpenVRLibrary; +import com.jme3.util.VRGuiManager; +import com.jme3.util.VRMouseManager; +import com.jme3.util.VRViewManager; +import com.jme3.util.VRViewManagerOSVR; +import com.jme3.util.VRViewManagerOpenVR; + +public class VREnvironment { + + private static final Logger logger = Logger.getLogger(VREnvironment.class.getName()); + + private VRAPI hardware = null; + private VRGuiManager guiManager = null; + private VRMouseManager mouseManager = null; + private VRViewManager viewmanager = null; + + /** + * The underlying system VR API. By default set to {@link VRConstants#SETTING_VRAPI_OPENVR_VALUE}. + */ + public int vrBinding = VRConstants.SETTING_VRAPI_OPENVR_VALUE; + + private boolean seated = false; + + private Spatial observer = null; + + private boolean forceVR = false; + + private boolean vrSupportedOS = false; + + private boolean nogui = false; + + private boolean compositorOS; + + private boolean useCompositor = true; + + private boolean instanceRendering = false; + + private boolean disableSwapBuffers = true; + + private float defaultFOV = 108f; + + private float defaultAspect = 1f; + + private AppSettings settings = null; + + private Application application = null; + + private Camera dummyCam = null; + + private AppState app = null; + + private boolean initialized = false; + + private boolean attached = false; + + public VREnvironment(AppSettings settings){ + + this.settings = settings; + + guiManager = new VRGuiManager(this); + mouseManager = new VRMouseManager(this); + dummyCam = new Camera(); + + processSettings(); + } + + /** + * Get the VR underlying hardware. + * @return the VR underlying hardware. + */ + public VRAPI getVRHardware() { + return hardware; + } + + /** + * Get the VR dedicated input. + * @return the VR dedicated input. + */ + public VRInputAPI getVRinput() { + if( hardware == null ){ + return null; + } + + return hardware.getVRinput(); + } + + /** + * Get the VR view manager. + * @return the VR view manager. + */ + public VRViewManager getVRViewManager() { + return viewmanager; + } + + /** + * Get the GUI manager attached to this environment. + * @return the GUI manager attached to this environment. + */ + public VRGuiManager getVRGUIManager(){ + return guiManager; + } + + /** + * Get the VR mouse manager attached to this environment. + * @return the VR mouse manager attached to this environment. + */ + public VRMouseManager getVRMouseManager(){ + return mouseManager; + } + + /** + * Can be used to change seated experience during runtime. + * @param isSeated true if designed for sitting, false for standing/roomscale + * @see #isSeatedExperience() + */ + public void setSeatedExperience(boolean isSeated) { + seated = isSeated; + if( hardware instanceof OpenVR ) { + if( hardware.getCompositor() == null ) { + return; + } + + if( seated ) { + ((OpenVR)hardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated); + } else { + ((OpenVR)hardware).getCompositor().SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding); + } + } + } + + /** + * Check if the application is configured as a seated experience. + * @return true if the application is configured as a seated experience and false otherwise. + * @see #setSeatedExperience(boolean) + */ + public boolean isSeatedExperience() { + return seated; + } + + /** + * Set the VR headset height from the ground. + * @param amount the VR headset height from the ground. + * @see #getVRHeightAdjustment() + */ + public void setVRHeightAdjustment(float amount) { + if( viewmanager != null ){ + viewmanager.setHeightAdjustment(amount); + } + } + + /** + * Get the VR headset height from the ground. + * @return the VR headset height from the ground. + * @see #setVRHeightAdjustment(float) + */ + public float getVRHeightAdjustment() { + if( viewmanager != null ){ + return viewmanager.getHeightAdjustment(); + } + return 0f; + } + + /** + * Get the scene observer. If no observer has been set, this method return the application {@link #getCamera() camera}. + * @return the scene observer. + * @see #setObserver(Spatial) + */ + public Object getObserver() { + if( observer == null ) { + + if (application != null){ + return application.getCamera(); + } else { + throw new IllegalStateException("VR environment is not attached to any application."); + } + } + return observer; + } + + /** + * Set the scene observer. The VR headset will be linked to it. If no observer is set, the VR headset is linked to the the application {@link #getCamera() camera}. + * @param observer the scene observer. + */ + public void setObserver(Spatial observer) { + this.observer = observer; + } + + /** + * Get the default Field Of View (FOV) value. + * @return the default Field Of View (FOV) value. + * @see #setDefaultFOV(float) + */ + public float getDefaultFOV() { + return defaultFOV; + } + + /** + * Set the default Field Of View (FOV) value. + * @param defaultFOV the default Field Of View (FOV) value. + * @see #getDefaultFOV() + */ + public void setDefaultFOV(float defaultFOV) { + this.defaultFOV = defaultFOV; + } + + /** + * Get the default aspect ratio. + * @return the default aspect ratio. + * @see #setDefaultAspect(float) + */ + public float getDefaultAspect() { + return defaultAspect; + } + + /** + * Set the default aspect ratio. + * @param defaultAspect the default aspect ratio. + * @see #getDefaultAspect() + */ + public void setDefaultAspect(float defaultAspect) { + this.defaultAspect = defaultAspect; + } + + /** + * Get the {@link AppSettings settings} attached to this environment. + * @return the {@link AppSettings settings} attached to this environment. + * @see #setSettings(AppSettings) + */ + public AppSettings getSettings(){ + return settings; + } + + /** + * Set the {@link AppSettings settings} attached to this environment. + * @param settings the {@link AppSettings settings} attached to this environment. + * @see #getSettings() + */ + public void setSettings(AppSettings settings){ + this.settings = settings; + processSettings(); + } + + /** + * Get if the system currently support VR. + * @return true if the system currently support VR and false otherwise. + */ + public boolean isVRSupported() { + return vrSupportedOS; + } + + /** + * Check if the VR mode is enabled. + * @return true if the VR mode is enabled and false otherwise. + */ + public boolean isInVR() { + return (forceVR || vrSupportedOS && hardware != null && hardware.isInitialized() && isInitialized()); + } + + /** + * Check if the rendering is instanced (see Geometry instancing). + * @return true if the rendering is instanced and false otherwise. + */ + public boolean isInstanceRendering() { + return instanceRendering; + } + + public boolean isSwapBuffers(){ + return disableSwapBuffers; + } + + /** + * Check if the application has a GUI overlay attached. + * @return true if the application has a GUI overlay attached and false otherwise. + */ + public boolean hasTraditionalGUIOverlay() { + return !nogui; + } + + /** + * Check if the VR environment is initialized. A call to the {@link #initialize() initialize()} method should set this value to true + * @return true if the VR environment is initialized and false otherwise. + */ + public boolean isInitialized(){ + return initialized; + } + + /** + * Is the VR compositor is active. + * @return true if the VR compositor is active and false otherwise. + */ + public boolean compositorAllowed() { + return useCompositor && compositorOS; + } + + /** + * Reset headset pose if seating experience. + */ + public void resetSeatedPose(){ + if( vrSupportedOS == false || isSeatedExperience() == false ){ + return; + } + getVRHardware().reset(); + } + + public AppState getAppState(){ + return app; + } + + public Application getApplication(){ + return application; + } + + /** + * Get the {@link Camera camera} used for rendering. + * If the VR mode is {@link #isInVR() active}, this method return a dummy camera, otherwise, + * this method return the camera of the attached application. + * @return the camera attached used for rendering. + */ + public Camera getCamera() { + if( isInVR() && getVRViewManager() != null && getVRViewManager().getLeftCamera() != null ) { + return dummyCam; + } + + return application.getCamera(); + } + + public Camera getDummyCamera(){ + + if (dummyCam == null){ + + if (application != null){ + + if (application.getCamera() != null){ + dummyCam = application.getCamera().clone(); + } else { + return new Camera(); + } + } else { + throw new IllegalStateException("VR environment is not attached to any application."); + } + } + + return dummyCam; + } + + /** + * Attach the VR environment to the given app state and application. + * This method should be called within the {@link AppState#stateAttached(com.jme3.app.state.AppStateManager) stateAttached(com.jme3.app.state.AppStateManager)} method + * from the app state. + * @param appState the app state to attach. + * @param application the application to attach. + */ + public void atttach(AppState appState, Application application){ + this.application = application; + this.app = appState; + + // Instanciate view manager + if (vrBinding == VRConstants.SETTING_VRAPI_OPENVR_VALUE){ + viewmanager = new VRViewManagerOpenVR(this); + } else if (vrBinding == VRConstants.SETTING_VRAPI_OSVR_VALUE){ + viewmanager = new VRViewManagerOSVR(this); + } else { + logger.severe("Cannot instanciate view manager, unknown VRAPI type: "+vrBinding); + } + } + + /** + * Initialize this VR environment. This method enable the system bindings and configure all the VR system modules. + * A call to this method has to be made before any use of VR capabilities. + * @return true if the VR environment is successfully initialized and false otherwise. + */ + public boolean initialize(){ + + logger.config("Initializing VR environment."); + + initialized = false; + + // we are going to use OpenVR now, not the Oculus Rift + // OpenVR does support the Rift + String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH); + vrSupportedOS = !OS.contains("nux") && System.getProperty("sun.arch.data.model").equalsIgnoreCase("64"); //for the moment, linux/unix causes crashes, 64-bit only + compositorOS = OS.contains("indows"); + + if( vrSupportedOS) { + if( vrBinding == VRConstants.SETTING_VRAPI_OSVR_VALUE ) { + hardware = new OSVR(this); + initialized = true; + logger.config("Creating OSVR wrapper [SUCCESS]"); + } else if( vrBinding == VRConstants.SETTING_VRAPI_OPENVR_VALUE ) { + hardware = new OpenVR(this); + initialized = true; + logger.config("Creating OpenVR wrapper [SUCCESS]"); + } else { + logger.config("Cannot create VR binding: "+vrBinding+" [FAILED]"); + logger.log(Level.SEVERE, "Cannot initialize VR environment [FAILED]"); + } + + if( hardware.initialize() ) { + initialized &= true; + logger.config("VR native wrapper initialized [SUCCESS]"); + } else { + initialized &= false; + logger.warning("VR native wrapper initialized [FAILED]"); + logger.log(Level.SEVERE, "Cannot initialize VR environment [FAILED]"); + } + } else { + logger.log(Level.SEVERE, "System does not support VR capabilities."); + logger.log(Level.SEVERE, "Cannot initialize VR environment [FAILED]"); + } + + return initialized; + } + + private void processSettings(){ + if (settings != null){ + + if (settings.get(VRConstants.SETTING_USE_COMPOSITOR) != null){ + useCompositor = settings.getBoolean(VRConstants.SETTING_USE_COMPOSITOR); + if( useCompositor == false ){ + disableSwapBuffers = false; + } + } + + if (settings.get(VRConstants.SETTING_ENABLE_MIRROR_WINDOW) != null){ + if( useCompositor == false ) { + disableSwapBuffers = false; + } else { + disableSwapBuffers = !settings.getBoolean(VRConstants.SETTING_ENABLE_MIRROR_WINDOW); + } + } + + if (settings.get(VRConstants.SETTING_GUI_OVERDRAW) != null){ + getVRGUIManager().setGuiOverdraw(settings.getBoolean(VRConstants.SETTING_GUI_OVERDRAW)); + } + + if (settings.get(VRConstants.SETTING_GUI_CURVED_SURFACE) != null){ + getVRGUIManager().setCurvedSurface(settings.getBoolean(VRConstants.SETTING_GUI_CURVED_SURFACE)); + } + + if (settings.get(VRConstants.SETTING_NO_GUI) != null){ + nogui = settings.getBoolean(VRConstants.SETTING_NO_GUI); + } + + if (settings.get(VRConstants.SETTING_VRAPI) != null){ + vrBinding = settings.getInteger(VRConstants.SETTING_VRAPI); + } + + if (settings.get(VRConstants.SETTING_SEATED_EXPERIENCE) != null){ + seated = settings.getBoolean(VRConstants.SETTING_SEATED_EXPERIENCE); + } + + if (settings.get(VRConstants.SETTING_INSTANCE_RENDERING) != null){ + instanceRendering = settings.getBoolean(VRConstants.SETTING_INSTANCE_RENDERING); + } + + if (settings.get(VRConstants.SETTING_DEFAULT_FOV) != null){ + defaultFOV = settings.getFloat(VRConstants.SETTING_DEFAULT_FOV); + } + + if (settings.get(VRConstants.SETTING_DEFAULT_ASPECT_RATIO) != null){ + defaultAspect = settings.getFloat(VRConstants.SETTING_DEFAULT_ASPECT_RATIO); + } + + if (settings.get(VRConstants.SETTING_FLIP_EYES) != null){ + if( getVRHardware() != null ){ + getVRHardware().setFlipEyes(settings.getBoolean(VRConstants.SETTING_FLIP_EYES)); + } + } + } + } +} diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/OSVR.java b/jme3-vr/src/main/java/com/jme3/input/vr/OSVR.java index 515e57d17..dce04e7b4 100644 --- a/jme3-vr/src/main/java/com/jme3/input/vr/OSVR.java +++ b/jme3-vr/src/main/java/com/jme3/input/vr/OSVR.java @@ -9,13 +9,22 @@ https://github.com/sensics/OSVR-RenderManager/blob/master/examples/RenderManager */ package com.jme3.input.vr; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; +import com.jme3.app.VREnvironment; import com.jme3.math.Matrix4f; import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; +import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary; +import com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary; +import com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.OSVR_DisplayConfig; +import com.jme3.system.osvr.osvrmatrixconventions.OSVR_Pose3; +import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_OpenResultsOpenGL; +import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderBufferOpenGL; +import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderInfoOpenGL; +import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderParams; +import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ViewportDescription; +import com.jme3.system.osvr.osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary; import com.ochafik.lang.jnaerator.runtime.NativeSize; import com.ochafik.lang.jnaerator.runtime.NativeSizeByReference; import com.sun.jna.Pointer; @@ -23,18 +32,6 @@ import com.sun.jna.ptr.PointerByReference; import java.nio.FloatBuffer; import java.util.logging.Logger; -import osvrclientkit.OsvrClientKitLibrary; -import osvrdisplay.OsvrDisplayLibrary; -import osvrdisplay.OsvrDisplayLibrary.OSVR_DisplayConfig; -import osvrmatrixconventions.OSVR_Pose3; - -import osvrrendermanageropengl.OSVR_OpenResultsOpenGL; -import osvrrendermanageropengl.OSVR_RenderBufferOpenGL; -import osvrrendermanageropengl.OSVR_RenderInfoOpenGL; -import osvrrendermanageropengl.OSVR_RenderParams; -import osvrrendermanageropengl.OSVR_ViewportDescription; -import osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary; - /** * A class that wraps an OSVR system. * @author reden - phr00t - https://github.com/phr00t @@ -87,7 +84,7 @@ public class OSVR implements VRAPI { OSVR_RenderParams.ByValue renderParams; OsvrClientKitLibrary.OSVR_ClientContext context; - osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary; + com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary; Pointer renderManager, renderManagerOpenGL, renderInfoCollection, registerBufferState; OSVRInput VRinput; NativeSize numRenderInfo; @@ -111,14 +108,14 @@ public class OSVR implements VRAPI { boolean initSuccess = false; boolean flipEyes = false; - private VRAppState app = null; + private VREnvironment environment = null; /** - * Create a new OSVR system attached to the given {@link VRAppState app state}. - * @param app the app state to which the input is attached. + * Create a new OSVR system attached to the given {@link VREnvironment VR environment}. + * @param environment the {@link VREnvironment VR environment} to which the input is attached. */ - public OSVR(VRAppState app){ - this.app = app; + public OSVR(VREnvironment environment){ + this.environment = environment; } /** @@ -150,7 +147,7 @@ public class OSVR implements VRAPI { hmdPose.setAutoSynch(false); context = OsvrClientKitLibrary.osvrClientInit(defaultJString, 0); - VRinput = new OSVRInput(app); + VRinput = new OSVRInput(environment); initSuccess = context != null && VRinput.init(); if( initSuccess ) { PointerByReference grabDisplay = new PointerByReference(); @@ -206,7 +203,7 @@ public class OSVR implements VRAPI { public boolean initVRCompositor(boolean allowed) { if( !allowed || renderManager != null ) return false; grabGLFWContext(); - graphicsLibrary = new osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue(); + graphicsLibrary = new com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue(); graphicsLibrary.toolkit = null; graphicsLibrary.setAutoSynch(false); grabRM = new PointerByReference(); grabRMOGL = new PointerByReference(); @@ -272,7 +269,7 @@ public class OSVR implements VRAPI { } @Override - public void _setFlipEyes(boolean set) { + public void setFlipEyes(boolean set) { flipEyes = set; } @@ -376,7 +373,7 @@ public class OSVR implements VRAPI { if( eyeLeftInfo == null ) return cam.getProjectionMatrix(); if( eyeMatrix[EYE_LEFT] == null ) { FloatBuffer tfb = FloatBuffer.allocate(16); - osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_LEFT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb); + com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_LEFT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb); eyeMatrix[EYE_LEFT] = new Matrix4f(); eyeMatrix[EYE_LEFT].set(tfb.get(0), tfb.get(4), tfb.get(8), tfb.get(12), tfb.get(1), tfb.get(5), tfb.get(9), tfb.get(13), @@ -391,7 +388,7 @@ public class OSVR implements VRAPI { if( eyeRightInfo == null ) return cam.getProjectionMatrix(); if( eyeMatrix[EYE_RIGHT] == null ) { FloatBuffer tfb = FloatBuffer.allocate(16); - osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_RIGHT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb); + com.jme3.system.osvr.osvrdisplay.OsvrDisplayLibrary.osvrClientGetViewerEyeSurfaceProjectionMatrixf(displayConfig, 0, (byte)EYE_RIGHT, 0, cam.getFrustumNear(), cam.getFrustumFar(), (short)0, tfb); eyeMatrix[EYE_RIGHT] = new Matrix4f(); eyeMatrix[EYE_RIGHT].set(tfb.get(0), tfb.get(4), tfb.get(8), tfb.get(12), tfb.get(1), tfb.get(5), tfb.get(9), tfb.get(13), @@ -461,10 +458,4 @@ public class OSVR implements VRAPI { public HmdType getType() { return HmdType.OSVR; } - - @Override - public VRAppState getVRAppState() { - return app; - } - } diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/OSVRInput.java b/jme3-vr/src/main/java/com/jme3/input/vr/OSVRInput.java index 85fc9a931..8d11f3a2e 100644 --- a/jme3-vr/src/main/java/com/jme3/input/vr/OSVRInput.java +++ b/jme3-vr/src/main/java/com/jme3/input/vr/OSVRInput.java @@ -7,26 +7,24 @@ package com.jme3.input.vr; import java.util.logging.Logger; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; +import com.jme3.app.VREnvironment; import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import com.jme3.scene.Spatial; +import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary; +import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary.OSVR_ClientInterface; +import com.jme3.system.osvr.osvrclientreporttypes.OSVR_AnalogReport; +import com.jme3.system.osvr.osvrclientreporttypes.OSVR_ButtonReport; +import com.jme3.system.osvr.osvrclientreporttypes.OSVR_Pose3; +import com.jme3.system.osvr.osvrinterface.OsvrInterfaceLibrary; +import com.jme3.system.osvr.osvrtimevalue.OSVR_TimeValue; +import com.jme3.util.VRViewManagerOSVR; import com.sun.jna.Callback; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; -import jmevr.util.VRViewManager; - -import osvrclientkit.OsvrClientKitLibrary; -import osvrclientkit.OsvrClientKitLibrary.OSVR_ClientInterface; -import osvrclientreporttypes.OSVR_AnalogReport; -import osvrclientreporttypes.OSVR_ButtonReport; -import osvrclientreporttypes.OSVR_Pose3; -import osvrinterface.OsvrInterfaceLibrary; -import osvrtimevalue.OSVR_TimeValue; /** * A class that wraps an OSVR input. @@ -64,7 +62,7 @@ public class OSVRInput implements VRInputAPI { private static final Vector2f lastCallAxis[] = new Vector2f[16]; private static float axisMultiplier = 1f; - private VRAppState app = null; + private VREnvironment environment = null; /** * Get the system String that identifies a controller. @@ -91,11 +89,11 @@ public class OSVRInput implements VRInputAPI { /** - * Create a new OSVR input attached to the given {@link VRAppState app state}. - * @param app the app state to which the input is attached. + * Create a new OSVR input attached to the given {@link VREnvironment VR environment}. + * @param environment the {@link VREnvironment VR environment} to which the input is attached. */ - public OSVRInput(VRAppState app){ - this.app = app; + public OSVRInput(VREnvironment environment){ + this.environment = environment; } @@ -167,7 +165,7 @@ public class OSVRInput implements VRInputAPI { private OSVR_ClientInterface getInterface(byte[] str) { PointerByReference pbr = new PointerByReference(); - OsvrClientKitLibrary.osvrClientGetInterface((OsvrClientKitLibrary.OSVR_ClientContext)app.getVRHardware().getVRSystem(), str, pbr); + OsvrClientKitLibrary.osvrClientGetInterface((OsvrClientKitLibrary.OSVR_ClientContext)environment.getVRHardware().getVRSystem(), str, pbr); return new OSVR_ClientInterface(pbr.getValue()); } @@ -303,9 +301,9 @@ public class OSVRInput implements VRInputAPI { @Override public Quaternion getFinalObserverRotation(int index) { - VRViewManager vrvm = app.getVRViewManager(); + VRViewManagerOSVR vrvm = (VRViewManagerOSVR)environment.getVRViewManager(); if( vrvm == null || isInputDeviceTracking(index) == false ) return null; - Object obs = app.getObserver(); + Object obs = environment.getObserver(); if( obs instanceof Camera ) { tempq.set(((Camera)obs).getRotation()); } else { @@ -316,9 +314,9 @@ public class OSVRInput implements VRInputAPI { @Override public Vector3f getFinalObserverPosition(int index) { - VRViewManager vrvm = app.getVRViewManager(); + VRViewManagerOSVR vrvm = (VRViewManagerOSVR) environment.getVRViewManager(); if( vrvm == null || isInputDeviceTracking(index) == false ) return null; - Object obs = app.getObserver(); + Object obs = environment.getObserver(); Vector3f pos = getPosition(index); if( obs instanceof Camera ) { ((Camera)obs).getRotation().mult(pos, pos); @@ -349,13 +347,6 @@ public class OSVRInput implements VRInputAPI { axisMultiplier = set; } - - @Override - public VRAppState getVRAppState() { - return app; - } - - @Override public VRTrackedController getTrackedController(int index) { // TODO Auto-generated method stub diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java index 3e7ff985d..8171bc48a 100644 --- a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java +++ b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVR.java @@ -5,8 +5,7 @@ */ package com.jme3.input.vr; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; +import com.jme3.app.VREnvironment; import com.jme3.math.Matrix4f; import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; @@ -19,22 +18,19 @@ import com.jme3.system.jopenvr.OpenVRUtil; import com.jme3.system.jopenvr.TrackedDevicePose_t; import com.jme3.system.jopenvr.VR_IVRCompositor_FnTable; import com.jme3.system.jopenvr.VR_IVRSystem_FnTable; +import com.jme3.util.VRUtil; import com.sun.jna.Memory; import com.sun.jna.Pointer; import com.sun.jna.ptr.FloatByReference; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; -import java.nio.FloatBuffer; import java.nio.IntBuffer; -import java.nio.LongBuffer; import java.util.Locale; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import jmevr.util.VRUtil; - /** * A class that wraps an OpenVR system. * @author reden - phr00t - https://github.com/phr00t @@ -84,15 +80,15 @@ public class OpenVR implements VRAPI { private static long frameCount; private static OpenVRInput VRinput; - private VRAppState app = null; + private VREnvironment environment = null; /** * Create a new OpenVR system - * attached to the given {@link VRAppState VR app state}. - * @param appState the VR app state to which the api is attached. + * attached to the given {@link VREnvironment VR environment}. + * @param environment the VR environment to which this API is attached. */ - public OpenVR(VRAppState appState){ - this.app = appState; + public OpenVR(VREnvironment environment){ + this.environment = environment; } @Override @@ -118,7 +114,7 @@ public class OpenVR implements VRAPI { private static long latencyWaitTime = 0; @Override - public void _setFlipEyes(boolean set) { + public void setFlipEyes(boolean set) { flipEyes = set; } @@ -180,7 +176,7 @@ public class OpenVR implements VRAPI { } // init controllers for the first time - VRinput = new OpenVRInput(app); + VRinput = new OpenVRInput(environment); VRinput.init(); VRinput.updateConnectedControllers(); @@ -206,7 +202,7 @@ public class OpenVR implements VRAPI { if(compositorFunctions != null && hmdErrorStore.getValue() == 0 ){ compositorFunctions.setAutoSynch(false); compositorFunctions.read(); - if( app.isSeatedExperience() ) { + if( environment.isSeatedExperience() ) { compositorFunctions.SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated); } else { compositorFunctions.SetTrackingSpace.apply(JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding); @@ -356,7 +352,7 @@ public class OpenVR implements VRAPI { frameCount = nowCount; vrsystemFunctions.GetDeviceToAbsoluteTrackingPose.apply( - app.isSeatedExperience()?JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated: + environment.isSeatedExperience()?JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseSeated: JOpenVRLibrary.ETrackingUniverseOrigin.ETrackingUniverseOrigin_TrackingUniverseStanding, fSecondsUntilPhotons, hmdTrackedDevicePoseReference, JOpenVRLibrary.k_unMaxTrackedDeviceCount); } @@ -373,7 +369,7 @@ public class OpenVR implements VRAPI { VRInput._updateConnectedControllers(); }*/ //update controllers pose information - app.getVRinput().updateControllerStates(); + environment.getVRinput().updateControllerStates(); // read pose data from native for (int nDevice = 0; nDevice < JOpenVRLibrary.k_unMaxTrackedDeviceCount; ++nDevice ){ @@ -447,7 +443,7 @@ public class OpenVR implements VRAPI { @Override public Vector3f getSeatedToAbsolutePosition() { - if( app.isSeatedExperience() == false ) return Vector3f.ZERO; + if( environment.isSeatedExperience() == false ) return Vector3f.ZERO; if( hmdSeatToStand == null ) { hmdSeatToStand = new Vector3f(); HmdMatrix34_t mat = vrsystemFunctions.GetSeatedZeroPoseToStandingAbsoluteTrackingPose.apply(); @@ -524,10 +520,5 @@ public class OpenVR implements VRAPI { return VRUtil.convertSteamVRMatrix3ToMatrix4f(mat, hmdPoseRightEye); } } - - @Override - public VRAppState getVRAppState() { - return app; - } - + } diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java index cb432b3da..0c565d0a1 100644 --- a/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java +++ b/jme3-vr/src/main/java/com/jme3/input/vr/OpenVRInput.java @@ -9,8 +9,7 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; +import com.jme3.app.VREnvironment; import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; @@ -20,9 +19,8 @@ import com.jme3.system.jopenvr.JOpenVRLibrary; import com.jme3.system.jopenvr.OpenVRUtil; import com.jme3.system.jopenvr.VRControllerState_t; import com.jme3.system.jopenvr.VR_IVRSystem_FnTable; - -import jmevr.util.VRUtil; -import jmevr.util.VRViewManager; +import com.jme3.util.VRUtil; +import com.jme3.util.VRViewManagerOpenVR; /* make helper functions to pull the following easily from raw data (DONE) @@ -98,16 +96,16 @@ public class OpenVRInput implements VRInputAPI { private final Quaternion tempq = new Quaternion(); - private VRAppState app; + private VREnvironment environment; private List trackedControllers = null; /** - * Create a new OpenVR input attached to the given application. - * @param application the application to which the input is attached. + * Create a new OpenVR input attached to the given VR environment. + * @param environment the VR environment to which the input is attached. */ - public OpenVRInput(VRAppState appState){ - this.app = appState; + public OpenVRInput(VREnvironment environment){ + this.environment = environment; } @Override @@ -297,18 +295,28 @@ public class OpenVRInput implements VRInputAPI { @Override public boolean isInputFocused() { - return ((VR_IVRSystem_FnTable)app.getVRHardware().getVRSystem()).IsInputFocusCapturedByAnotherProcess.apply() == 0; + + if (environment != null){ + return ((VR_IVRSystem_FnTable)environment.getVRHardware().getVRSystem()).IsInputFocusCapturedByAnotherProcess.apply() == 0; + } else { + throw new IllegalStateException("VR input is not attached to a VR environment."); + } } @Override public boolean isInputDeviceTracking(int index) { - if( index < 0 || index >= controllerCount ) return false; + if( index < 0 || index >= controllerCount ){ + return false; + } + return OpenVR.hmdTrackedDevicePoses[controllerIndex[index]].bPoseIsValid != 0; } @Override public Quaternion getOrientation(int index) { - if( isInputDeviceTracking(index) == false ) return null; + if( isInputDeviceTracking(index) == false ){ + return null; + } index = controllerIndex[index]; VRUtil.convertMatrix4toQuat(OpenVR.poseMatrices[index], rotStore[index]); return rotStore[index]; @@ -316,7 +324,10 @@ public class OpenVRInput implements VRInputAPI { @Override public Vector3f getPosition(int index) { - if( isInputDeviceTracking(index) == false ) return null; + if( isInputDeviceTracking(index) == false ){ + return null; + } + // the hmdPose comes in rotated funny, fix that here index = controllerIndex[index]; OpenVR.poseMatrices[index].toTranslationVector(posStore[index]); @@ -327,84 +338,122 @@ public class OpenVRInput implements VRInputAPI { @Override public Quaternion getFinalObserverRotation(int index) { - VRViewManager vrvm = app.getVRViewManager(); - if( vrvm == null || isInputDeviceTracking(index) == false ) return null; - Object obs = app.getObserver(); - if( obs instanceof Camera ) { - tempq.set(((Camera)obs).getRotation()); - } else { - tempq.set(((Spatial)obs).getWorldRotation()); - } - return tempq.multLocal(getOrientation(index)); + + if (environment != null){ + VRViewManagerOpenVR vrvm = (VRViewManagerOpenVR)environment.getVRViewManager(); + + if (vrvm != null){ + if(isInputDeviceTracking(index) == false ){ + return null; + } + + Object obs = environment.getObserver(); + if( obs instanceof Camera ) { + tempq.set(((Camera)obs).getRotation()); + } else { + tempq.set(((Spatial)obs).getWorldRotation()); + } + + return tempq.multLocal(getOrientation(index)); + } else { + throw new IllegalStateException("VR environment has no valid view manager."); + } + + + } else { + throw new IllegalStateException("VR input is not attached to a VR environment."); + } } @Override public Vector3f getFinalObserverPosition(int index) { - VRViewManager vrvm = app.getVRViewManager(); - if( vrvm == null || isInputDeviceTracking(index) == false ) return null; - Object obs = app.getObserver(); - Vector3f pos = getPosition(index); - if( obs instanceof Camera ) { - ((Camera)obs).getRotation().mult(pos, pos); - return pos.addLocal(((Camera)obs).getLocation()); - } else { - ((Spatial)obs).getWorldRotation().mult(pos, pos); - return pos.addLocal(((Spatial)obs).getWorldTranslation()); - } + + if (environment != null){ + VRViewManagerOpenVR vrvm = (VRViewManagerOpenVR)environment.getVRViewManager(); + + if (vrvm != null){ + if(isInputDeviceTracking(index) == false ){ + return null; + } + Object obs = environment.getObserver(); + Vector3f pos = getPosition(index); + if( obs instanceof Camera ) { + ((Camera)obs).getRotation().mult(pos, pos); + return pos.addLocal(((Camera)obs).getLocation()); + } else { + ((Spatial)obs).getWorldRotation().mult(pos, pos); + return pos.addLocal(((Spatial)obs).getWorldTranslation()); + } + } else { + throw new IllegalStateException("VR environment has no valid view manager."); + } + + } else { + throw new IllegalStateException("VR input is not attached to a VR environment."); + } } @Override public void triggerHapticPulse(int controllerIndex, float seconds) { - if( app.isInVR() == false || isInputDeviceTracking(controllerIndex) == false ) return; + if( environment.isInVR() == false || isInputDeviceTracking(controllerIndex) == false ){ + return; + } + // apparently only axis ID of 0 works - ((VR_IVRSystem_FnTable)app.getVRHardware().getVRSystem()).TriggerHapticPulse.apply(OpenVRInput.controllerIndex[controllerIndex], + ((VR_IVRSystem_FnTable)environment.getVRHardware().getVRSystem()).TriggerHapticPulse.apply(OpenVRInput.controllerIndex[controllerIndex], 0, (short)Math.round(3f * seconds / 1e-3f)); } @Override public void updateConnectedControllers() { logger.config("Updating connected controllers."); - controllerCount = 0; - for(int i=0;itrue if the initialization is a success and false otherwise. */ public boolean initVRCompositor(boolean allowed); - - /** - * Get the {@link VRAppState VR app state} to which this api is attached. - * @return the VR app state to which this input is attached. - */ - public VRAppState getVRAppState(); - + /** * Get the object that wraps natively the VR system. * @return the object that wraps natively the VR system. @@ -63,10 +56,10 @@ public interface VRAPI { public VRInputAPI getVRinput(); /** - * Do not use. Prefers the preconfigure routine from the VRApplication. + * Flip the left and right eye.. * @param set true if the eyes has to be flipped and false otherwise. */ - public void _setFlipEyes(boolean set); + public void setFlipEyes(boolean set); /** * Set if latency information has to be logged. diff --git a/jme3-vr/src/main/java/com/jme3/input/vr/VRInputAPI.java b/jme3-vr/src/main/java/com/jme3/input/vr/VRInputAPI.java index 1e2c94dbc..50733e04b 100644 --- a/jme3-vr/src/main/java/com/jme3/input/vr/VRInputAPI.java +++ b/jme3-vr/src/main/java/com/jme3/input/vr/VRInputAPI.java @@ -5,8 +5,6 @@ */ package com.jme3.input.vr; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; @@ -197,9 +195,4 @@ public interface VRInputAPI { */ public void triggerHapticPulse(int controllerIndex, float seconds); - /** - * Get the {@link VRAppState VR app state} to which this api is attached. - * @return the VR app state to which this input is attached. - */ - public VRAppState getVRAppState(); } diff --git a/jme3-vr/src/main/java/jmevr/util/FilterUtil.java b/jme3-vr/src/main/java/com/jme3/post/FilterUtil.java similarity index 95% rename from jme3-vr/src/main/java/jmevr/util/FilterUtil.java rename to jme3-vr/src/main/java/com/jme3/post/FilterUtil.java index 70214aa6b..c29592d10 100644 --- a/jme3-vr/src/main/java/jmevr/util/FilterUtil.java +++ b/jme3-vr/src/main/java/com/jme3/post/FilterUtil.java @@ -2,7 +2,7 @@ * To change this template, choose Tools | Templates * and open the template in the editor. */ -package jmevr.util; +package com.jme3.post; import com.jme3.asset.AssetManager; import com.jme3.post.filters.FogFilter; diff --git a/jme3-vr/src/main/java/jmevr/util/CenterQuad.java b/jme3-vr/src/main/java/com/jme3/scene/CenterQuad.java similarity index 99% rename from jme3-vr/src/main/java/jmevr/util/CenterQuad.java rename to jme3-vr/src/main/java/com/jme3/scene/CenterQuad.java index 7564afdba..87aeda14b 100644 --- a/jme3-vr/src/main/java/jmevr/util/CenterQuad.java +++ b/jme3-vr/src/main/java/com/jme3/scene/CenterQuad.java @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package jmevr.util; +package com.jme3.scene; import com.jme3.scene.Mesh; import com.jme3.scene.VertexBuffer.Type; diff --git a/jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowRendererVR.java b/jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowRendererVR.java index f11eb9704..323a452ec 100644 --- a/jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowRendererVR.java +++ b/jme3-vr/src/main/java/com/jme3/shadow/AbstractShadowRendererVR.java @@ -45,6 +45,7 @@ import com.jme3.math.Matrix4f; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.post.SceneProcessor; +import com.jme3.profile.AppProfiler; import com.jme3.renderer.Camera; import com.jme3.renderer.RenderManager; import com.jme3.renderer.Renderer; @@ -100,6 +101,8 @@ public abstract class AbstractShadowRendererVR implements SceneProcessor, Savabl protected RenderState forcedRenderState = new RenderState(); protected Boolean renderBackFacesShadows; + protected AppProfiler profiler = null; + /** * true if the fallback material should be used, otherwise false */ @@ -379,6 +382,11 @@ public abstract class AbstractShadowRendererVR implements SceneProcessor, Savabl */ protected abstract Camera getShadowCam(int shadowMapIndex); + @Override + public void setProfiler(AppProfiler profiler) { + this.profiler = profiler; + } + /** * responsible for displaying the frustum of the shadow cam for debug * purpose diff --git a/jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowRendererVR.java b/jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowRendererVR.java index 941b97cc5..f9bdd1f59 100644 --- a/jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowRendererVR.java +++ b/jme3-vr/src/main/java/com/jme3/shadow/DirectionalLightShadowRendererVR.java @@ -42,7 +42,6 @@ import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; -import com.jme3.profile.AppProfiler; import com.jme3.renderer.Camera; import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.RenderQueue; @@ -76,8 +75,6 @@ public class DirectionalLightShadowRendererVR extends AbstractShadowRendererVR { protected Vector3f[] points = new Vector3f[8]; //Holding the info for fading shadows in the far distance private boolean stabilize = true; - - private AppProfiler profiler = null; /** * Used for serialzation use @@ -304,9 +301,4 @@ public class DirectionalLightShadowRendererVR extends AbstractShadowRendererVR { protected boolean checkCulling(Camera viewCam) { return true; } - - @Override - public void setProfiler(AppProfiler profiler) { - this.profiler = profiler; - } } diff --git a/jme3-vr/src/main/java/com/jme3/shadow/InstancedDirectionalShadowFilter.java b/jme3-vr/src/main/java/com/jme3/shadow/InstancedDirectionalShadowFilter.java index 410137305..1ad3cf85d 100644 --- a/jme3-vr/src/main/java/com/jme3/shadow/InstancedDirectionalShadowFilter.java +++ b/jme3-vr/src/main/java/com/jme3/shadow/InstancedDirectionalShadowFilter.java @@ -5,13 +5,13 @@ */ package com.jme3.shadow; -import com.jme3.app.VRApplication; +import com.jme3.app.Application; import com.jme3.math.Matrix4f; import com.jme3.math.Vector4f; import com.jme3.renderer.Camera; /** - * An instanced version of the {@link DirectionalLightShadowFilterVR directional light shadow filter}. + * An instanced version of the {@link DirectionalLightShadowFilterVR directional light shadow filter} dedi. * @author reden - phr00t - https://github.com/phr00t * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org */ @@ -19,30 +19,53 @@ public class InstancedDirectionalShadowFilter extends DirectionalLightShadowFilt private final Vector4f temp4f = new Vector4f(), temp4f2 = new Vector4f(); - private VRApplication application; + private boolean instanceRendering = false; + + private Camera rightCamera = null; - /** + /** * Create a new instanced version of the {@link DirectionalLightShadowFilterVR directional light shadow filter}. - * @param application the VR application that this filter is attached to. + * @param application the application that this filter is attached to. * @param camera * @param shadowMapSize the size of the rendered shadowmaps (512, 1024, 2048, etc...) * @param nbSplits the number of shadow maps rendered (the more shadow maps the more quality, the less fps). * @param instancedRendering true if this filter has to use instance rendering and false otherwise. + * @param rightCamera the camera used as right eye in stereo rendering mode. */ - public InstancedDirectionalShadowFilter(VRApplication application, Camera camera, int shadowMapSize, int nbSplits, boolean instancedRendering) { + public InstancedDirectionalShadowFilter(Application application, Camera camera, int shadowMapSize, int nbSplits, boolean instancedRendering, Camera rightCamera) { super(application.getAssetManager(), shadowMapSize, nbSplits, "Common/MatDefs/VR/PostShadowFilter.j3md"); + this.instanceRendering = instancedRendering; + this.rightCamera = rightCamera; } @Override protected void preFrame(float tpf) { shadowRenderer.preFrame(tpf); - if( application.isInstanceVRRendering() ) { - material.setMatrix4("ViewProjectionMatrixInverseRight", application.getVRViewManager().getRightCamera().getViewProjectionMatrix().invert()); - Matrix4f m = application.getVRViewManager().getRightCamera().getViewProjectionMatrix(); + if( instanceRendering ) { + material.setMatrix4("ViewProjectionMatrixInverseRight", rightCamera.getViewProjectionMatrix().invert()); + Matrix4f m = rightCamera.getViewProjectionMatrix(); material.setVector4("ViewProjectionMatrixRow2Right", temp4f2.set(m.m20, m.m21, m.m22, m.m23)); } material.setMatrix4("ViewProjectionMatrixInverse", viewPort.getCamera().getViewProjectionMatrix().invert()); Matrix4f m = viewPort.getCamera().getViewProjectionMatrix(); material.setVector4("ViewProjectionMatrixRow2", temp4f.set(m.m20, m.m21, m.m22, m.m23)); } + + /** + * Get if this filter is using instance rendering. + * @return true if this filter is using instance rendering and false otherwise. + * @see #setInstanceRendering(boolean) + */ + public boolean isInstanceRendering() { + return instanceRendering; + } + + /** + * Set if this filter has to use instance rendering. + * @param instanceRendering true if this filter has to use instance rendering and false otherwise. + * @see #isInstanceRendering() + */ + public void setInstanceRendering(boolean instanceRendering) { + this.instanceRendering = instanceRendering; + } } diff --git a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglWindowVR.java b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglWindowVR.java index 3918aeda6..95a1f8420 100644 --- a/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglWindowVR.java +++ b/jme3-vr/src/main/java/com/jme3/system/lwjgl/LwjglWindowVR.java @@ -39,14 +39,12 @@ import com.jme3.input.TouchInput; import com.jme3.input.lwjgl.GlfwJoystickInput; import com.jme3.input.lwjgl.GlfwKeyInputVR; import com.jme3.input.lwjgl.GlfwMouseInputVR; -import com.jme3.renderer.opengl.GL; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.JmeSystem; import com.jme3.system.NanoTimer; import org.lwjgl.glfw.*; -import org.lwjgl.opengl.GL11; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; diff --git a/jme3-vr/src/main/java/osvrclientkit/OsvrClientKitLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientkit/OsvrClientKitLibrary.java similarity index 99% rename from jme3-vr/src/main/java/osvrclientkit/OsvrClientKitLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientkit/OsvrClientKitLibrary.java index 23975954d..6c5b32e03 100644 --- a/jme3-vr/src/main/java/osvrclientkit/OsvrClientKitLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientkit/OsvrClientKitLibrary.java @@ -1,4 +1,4 @@ -package osvrclientkit; +package com.jme3.system.osvr.osvrclientkit; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.Native; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AccelerationReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AccelerationReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AccelerationReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AccelerationReport.java index 454d72949..61592a5b3 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AccelerationReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AccelerationReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AccelerationState.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AccelerationState.java similarity index 97% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AccelerationState.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AccelerationState.java index aecd5ba51..ccf4837ce 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AccelerationState.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AccelerationState.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AnalogReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AnalogReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AnalogReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AnalogReport.java index 9c0156080..0f84cdfea 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AnalogReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AnalogReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AngularAccelerationReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AngularAccelerationReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AngularAccelerationReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AngularAccelerationReport.java index 761fab4d0..1afbe795b 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AngularAccelerationReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AngularAccelerationReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AngularVelocityReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AngularVelocityReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AngularVelocityReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AngularVelocityReport.java index 496e6f503..5926ec745 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_AngularVelocityReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_AngularVelocityReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_ButtonReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_ButtonReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_ButtonReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_ButtonReport.java index fdc0b91e3..ad3ab53be 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_ButtonReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_ButtonReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_DirectionReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_DirectionReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_DirectionReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_DirectionReport.java index 624c9833d..78ca84a39 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_DirectionReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_DirectionReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker2DReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker2DReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker2DReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker2DReport.java index 335e146e8..fab1548e2 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker2DReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker2DReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker3DReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker3DReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker3DReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker3DReport.java index 4de93a11e..a42192be8 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker3DReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker3DReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker3DState.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker3DState.java similarity index 97% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker3DState.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker3DState.java index aef54362b..07eb1d880 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTracker3DState.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTracker3DState.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTrackerBlinkReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTrackerBlinkReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTrackerBlinkReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTrackerBlinkReport.java index 96c6992b2..4d051bbd2 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_EyeTrackerBlinkReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_EyeTrackerBlinkReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_IncrementalQuaternion.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_IncrementalQuaternion.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_IncrementalQuaternion.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_IncrementalQuaternion.java index 2630cafd5..66f04ba4e 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_IncrementalQuaternion.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_IncrementalQuaternion.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_LinearAccelerationReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_LinearAccelerationReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_LinearAccelerationReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_LinearAccelerationReport.java index 20368ec95..e93333f59 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_LinearAccelerationReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_LinearAccelerationReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_LinearVelocityReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_LinearVelocityReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_LinearVelocityReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_LinearVelocityReport.java index 2eddb9a4e..daca276bc 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_LinearVelocityReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_LinearVelocityReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Location2DReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Location2DReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Location2DReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Location2DReport.java index 2f1eb8561..75e9ea1e3 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Location2DReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Location2DReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_NaviPositionReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_NaviPositionReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_NaviPositionReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_NaviPositionReport.java index 3472e1ae3..641018a97 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_NaviPositionReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_NaviPositionReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_NaviVelocityReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_NaviVelocityReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_NaviVelocityReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_NaviVelocityReport.java index e4e80cfb1..89dcef250 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_NaviVelocityReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_NaviVelocityReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_OrientationReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_OrientationReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_OrientationReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_OrientationReport.java index b08346151..2699487f1 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_OrientationReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_OrientationReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Pose3.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Pose3.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Pose3.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Pose3.java index c1eaa9a85..a9ce1c202 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Pose3.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Pose3.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_PoseReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_PoseReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_PoseReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_PoseReport.java index 2985e864f..f80bfd06b 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_PoseReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_PoseReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_PositionReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_PositionReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_PositionReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_PositionReport.java index b12434c6d..718682835 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_PositionReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_PositionReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Quaternion.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Quaternion.java similarity index 96% rename from jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Quaternion.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Quaternion.java index 07b83b1e5..48f83f607 100644 --- a/jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Quaternion.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Quaternion.java @@ -1,4 +1,4 @@ -package osvrmatrixconventions; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Vec2.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Vec2.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Vec2.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Vec2.java index dc606d33f..28a5453a2 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Vec2.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Vec2.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Vec3.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Vec3.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Vec3.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Vec3.java index 40008b5e2..96c81a65c 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Vec3.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_Vec3.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_VelocityReport.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_VelocityReport.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_VelocityReport.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_VelocityReport.java index cdeab701e..103f351d8 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_VelocityReport.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_VelocityReport.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_VelocityState.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_VelocityState.java similarity index 97% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_VelocityState.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_VelocityState.java index 8306902af..de34de0cd 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_VelocityState.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OSVR_VelocityState.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OsvrClientReportTypesLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OsvrClientReportTypesLibrary.java similarity index 98% rename from jme3-vr/src/main/java/osvrclientreporttypes/OsvrClientReportTypesLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OsvrClientReportTypesLibrary.java index 66950ef8d..7933cdefe 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OsvrClientReportTypesLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrclientreporttypes/OsvrClientReportTypesLibrary.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrclientreporttypes; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; diff --git a/jme3-vr/src/main/java/osvrdisplay/OsvrDisplayLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrdisplay/OsvrDisplayLibrary.java similarity index 99% rename from jme3-vr/src/main/java/osvrdisplay/OsvrDisplayLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrdisplay/OsvrDisplayLibrary.java index c9c7334f0..38489ecdf 100644 --- a/jme3-vr/src/main/java/osvrdisplay/OsvrDisplayLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrdisplay/OsvrDisplayLibrary.java @@ -1,4 +1,5 @@ -package osvrdisplay; +package com.jme3.system.osvr.osvrdisplay; +import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; @@ -12,7 +13,7 @@ import java.nio.ByteBuffer; import java.nio.DoubleBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; -import osvrclientkit.OsvrClientKitLibrary; + /** * JNA Wrapper for library osvrDisplay
* This file was autogenerated by JNAerator,
diff --git a/jme3-vr/src/main/java/osvrinterface/OsvrInterfaceLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrinterface/OsvrInterfaceLibrary.java similarity index 81% rename from jme3-vr/src/main/java/osvrinterface/OsvrInterfaceLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrinterface/OsvrInterfaceLibrary.java index bf9b614b8..2a1c69476 100644 --- a/jme3-vr/src/main/java/osvrinterface/OsvrInterfaceLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrinterface/OsvrInterfaceLibrary.java @@ -1,10 +1,10 @@ -package osvrinterface; +package com.jme3.system.osvr.osvrinterface; +import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary.OSVR_ClientInterface; +import com.jme3.system.osvr.osvrclientreporttypes.OSVR_Pose3; +import com.jme3.system.osvr.osvrtimevalue.OSVR_TimeValue; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; -import osvrclientkit.OsvrClientKitLibrary.OSVR_ClientInterface; -import osvrclientreporttypes.OSVR_Pose3; -import osvrtimevalue.OSVR_TimeValue; /** * JNA Wrapper for library osvrInterface
* This file was autogenerated by JNAerator,
diff --git a/jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Pose3.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Pose3.java similarity index 96% rename from jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Pose3.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Pose3.java index dd3b250dc..8925e2c6e 100644 --- a/jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Pose3.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Pose3.java @@ -1,4 +1,4 @@ -package osvrmatrixconventions; +package com.jme3.system.osvr.osvrmatrixconventions; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Quaternion.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Quaternion.java similarity index 96% rename from jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Quaternion.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Quaternion.java index 7a1c4c4b5..04c914594 100644 --- a/jme3-vr/src/main/java/osvrclientreporttypes/OSVR_Quaternion.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Quaternion.java @@ -1,4 +1,4 @@ -package osvrclientreporttypes; +package com.jme3.system.osvr.osvrmatrixconventions; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Vec3.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Vec3.java similarity index 96% rename from jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Vec3.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Vec3.java index 62733630a..31db1607a 100644 --- a/jme3-vr/src/main/java/osvrmatrixconventions/OSVR_Vec3.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OSVR_Vec3.java @@ -1,4 +1,4 @@ -package osvrmatrixconventions; +package com.jme3.system.osvr.osvrmatrixconventions; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrmatrixconventions/OsvrMatrixConventionsLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OsvrMatrixConventionsLibrary.java similarity index 99% rename from jme3-vr/src/main/java/osvrmatrixconventions/OsvrMatrixConventionsLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OsvrMatrixConventionsLibrary.java index 04330c772..e32f3813a 100644 --- a/jme3-vr/src/main/java/osvrmatrixconventions/OsvrMatrixConventionsLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrmatrixconventions/OsvrMatrixConventionsLibrary.java @@ -1,4 +1,4 @@ -package osvrmatrixconventions; +package com.jme3.system.osvr.osvrmatrixconventions; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; diff --git a/jme3-vr/src/main/java/osvrrendermanager/OSVR_ProjectionMatrix.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_ProjectionMatrix.java similarity index 97% rename from jme3-vr/src/main/java/osvrrendermanager/OSVR_ProjectionMatrix.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_ProjectionMatrix.java index fe7880289..16a1dc6b4 100644 --- a/jme3-vr/src/main/java/osvrrendermanager/OSVR_ProjectionMatrix.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_ProjectionMatrix.java @@ -1,4 +1,4 @@ -package osvrrendermanager; +package com.jme3.system.osvr.osvrrendermanager; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanager/OSVR_RGB.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_RGB.java similarity index 95% rename from jme3-vr/src/main/java/osvrrendermanager/OSVR_RGB.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_RGB.java index d4b96fefe..09695a57b 100644 --- a/jme3-vr/src/main/java/osvrrendermanager/OSVR_RGB.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_RGB.java @@ -1,4 +1,4 @@ -package osvrrendermanager; +package com.jme3.system.osvr.osvrrendermanager; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderParams.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_RenderParams.java similarity index 97% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderParams.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_RenderParams.java index 02453f47b..742175010 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderParams.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_RenderParams.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanager; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanager/OSVR_ViewportDescription.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_ViewportDescription.java similarity index 97% rename from jme3-vr/src/main/java/osvrrendermanager/OSVR_ViewportDescription.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_ViewportDescription.java index c29f5db02..e3528fad0 100644 --- a/jme3-vr/src/main/java/osvrrendermanager/OSVR_ViewportDescription.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OSVR_ViewportDescription.java @@ -1,4 +1,4 @@ -package osvrrendermanager; +package com.jme3.system.osvr.osvrrendermanager; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanager/OsvrRenderManagerLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OsvrRenderManagerLibrary.java similarity index 82% rename from jme3-vr/src/main/java/osvrrendermanager/OsvrRenderManagerLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OsvrRenderManagerLibrary.java index 577ecae24..64e71afc6 100644 --- a/jme3-vr/src/main/java/osvrrendermanager/OsvrRenderManagerLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanager/OsvrRenderManagerLibrary.java @@ -1,4 +1,4 @@ -package osvrrendermanager; +package com.jme3.system.osvr.osvrrendermanager; import com.ochafik.lang.jnaerator.runtime.NativeSizeByReference; import com.sun.jna.Library; import com.sun.jna.Native; @@ -62,7 +62,7 @@ public class OsvrRenderManagerLibrary implements Library { */ public static native byte osvrRenderManagerFinishRegisterRenderBuffers(Pointer renderManager, Pointer registerBufferState, byte appWillNotOverwriteBeforeNewPresent); /** Original signature : OSVR_ReturnCode osvrRenderManagerPresentSolidColorf(OSVR_RenderManager, OSVR_RGB_FLOAT) */ - public static native byte osvrRenderManagerPresentSolidColorf(Pointer renderManager, osvrrendermanager.OSVR_RGB.ByValue rgb); + public static native byte osvrRenderManagerPresentSolidColorf(Pointer renderManager, com.jme3.system.osvr.osvrrendermanager.OSVR_RGB.ByValue rgb); /** * when you're done.
* Original signature : OSVR_ReturnCode osvrRenderManagerGetRenderInfoCollection(OSVR_RenderManager, OSVR_RenderParams, OSVR_RenderInfoCollection*) @@ -81,37 +81,37 @@ public class OsvrRenderManagerLibrary implements Library { /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_OpenGL(double*, OSVR_ProjectionMatrix)
- * @deprecated use the safer methods {@link #OSVR_Projection_to_OpenGL(java.nio.DoubleBuffer, osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_OpenGL(com.sun.jna.ptr.DoubleByReference, osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} instead + * @deprecated use the safer methods {@link #OSVR_Projection_to_OpenGL(java.nio.DoubleBuffer, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_OpenGL(com.sun.jna.ptr.DoubleByReference, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} instead */ @Deprecated - public static native byte OSVR_Projection_to_OpenGL(DoubleByReference OpenGL_out, osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_OpenGL(DoubleByReference OpenGL_out, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_OpenGL(double*, OSVR_ProjectionMatrix) */ - public static native byte OSVR_Projection_to_OpenGL(DoubleBuffer OpenGL_out, osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_OpenGL(DoubleBuffer OpenGL_out, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_D3D(float[16], OSVR_ProjectionMatrix)
- * @deprecated use the safer methods {@link #OSVR_Projection_to_D3D(java.nio.FloatBuffer, osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_D3D(com.sun.jna.ptr.FloatByReference, osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} instead + * @deprecated use the safer methods {@link #OSVR_Projection_to_D3D(java.nio.FloatBuffer, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_D3D(com.sun.jna.ptr.FloatByReference, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} instead */ @Deprecated - public static native byte OSVR_Projection_to_D3D(FloatByReference D3D_out, osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_D3D(FloatByReference D3D_out, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_D3D(float[16], OSVR_ProjectionMatrix) */ - public static native byte OSVR_Projection_to_D3D(FloatBuffer D3D_out, osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_D3D(FloatBuffer D3D_out, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_Unreal(float[16], OSVR_ProjectionMatrix)
- * @deprecated use the safer methods {@link #OSVR_Projection_to_Unreal(java.nio.FloatBuffer, osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_Unreal(com.sun.jna.ptr.FloatByReference, osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} instead + * @deprecated use the safer methods {@link #OSVR_Projection_to_Unreal(java.nio.FloatBuffer, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_Unreal(com.sun.jna.ptr.FloatByReference, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue)} instead */ @Deprecated - public static native byte OSVR_Projection_to_Unreal(FloatByReference Unreal_out, osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_Unreal(FloatByReference Unreal_out, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_Unreal(float[16], OSVR_ProjectionMatrix) */ - public static native byte OSVR_Projection_to_Unreal(FloatBuffer Unreal_out, osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_Unreal(FloatBuffer Unreal_out, com.jme3.system.osvr.osvrrendermanager.OSVR_ProjectionMatrix.ByValue projection_in); } diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_GraphicsLibraryOpenGL.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_GraphicsLibraryOpenGL.java similarity index 81% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_GraphicsLibraryOpenGL.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_GraphicsLibraryOpenGL.java index 800723c27..626609e08 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_GraphicsLibraryOpenGL.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_GraphicsLibraryOpenGL.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; @@ -10,7 +10,7 @@ import java.util.List; */ public class OSVR_GraphicsLibraryOpenGL extends Structure { /** C type : const OSVR_OpenGLToolkitFunctions* */ - public osvrrendermanageropengl.OSVR_OpenGLToolkitFunctions.ByReference toolkit; + public com.jme3.system.osvr.osvrrendermanageropengl.OSVR_OpenGLToolkitFunctions.ByReference toolkit; public OSVR_GraphicsLibraryOpenGL() { super(); } @@ -18,7 +18,7 @@ public class OSVR_GraphicsLibraryOpenGL extends Structure { return Arrays.asList("toolkit"); } /** @param toolkit C type : const OSVR_OpenGLToolkitFunctions* */ - public OSVR_GraphicsLibraryOpenGL(osvrrendermanageropengl.OSVR_OpenGLToolkitFunctions.ByReference toolkit) { + public OSVR_GraphicsLibraryOpenGL(com.jme3.system.osvr.osvrrendermanageropengl.OSVR_OpenGLToolkitFunctions.ByReference toolkit) { super(); this.toolkit = toolkit; } diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenGLContextParams.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenGLContextParams.java similarity index 97% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenGLContextParams.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenGLContextParams.java index 67726b8e2..71a67ee1a 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenGLContextParams.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenGLContextParams.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenGLToolkitFunctions.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenGLToolkitFunctions.java similarity index 98% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenGLToolkitFunctions.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenGLToolkitFunctions.java index fcc6d94a4..0b996bcec 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenGLToolkitFunctions.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenGLToolkitFunctions.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.ochafik.lang.jnaerator.runtime.NativeSize; import com.sun.jna.Callback; import com.sun.jna.Pointer; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenResultsOpenGL.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenResultsOpenGL.java similarity index 96% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenResultsOpenGL.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenResultsOpenGL.java index 1bb1a3427..7032d8457 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_OpenResultsOpenGL.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_OpenResultsOpenGL.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_ProjectionMatrix.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_ProjectionMatrix.java similarity index 96% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_ProjectionMatrix.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_ProjectionMatrix.java index 0a300d47a..5aabd8844 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_ProjectionMatrix.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_ProjectionMatrix.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RGB.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RGB.java similarity index 95% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RGB.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RGB.java index 6e9af7239..fb5a925b3 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RGB.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RGB.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderBufferOpenGL.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderBufferOpenGL.java similarity index 96% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderBufferOpenGL.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderBufferOpenGL.java index 6cfd0b693..d2488eff9 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderBufferOpenGL.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderBufferOpenGL.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderInfoOpenGL.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderInfoOpenGL.java similarity index 94% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderInfoOpenGL.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderInfoOpenGL.java index 1c1eeea14..3b0e1a79f 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_RenderInfoOpenGL.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderInfoOpenGL.java @@ -1,9 +1,9 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; +import com.jme3.system.osvr.osvrmatrixconventions.OSVR_Pose3; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; import java.util.List; -import osvrmatrixconventions.OSVR_Pose3; /** * This file was autogenerated by JNAerator,
* a tool written by Olivier Chafik that uses a few opensource projects..
diff --git a/jme3-vr/src/main/java/osvrrendermanager/OSVR_RenderParams.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderParams.java similarity index 97% rename from jme3-vr/src/main/java/osvrrendermanager/OSVR_RenderParams.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderParams.java index 6ecd5f5a8..ef560519d 100644 --- a/jme3-vr/src/main/java/osvrrendermanager/OSVR_RenderParams.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_RenderParams.java @@ -1,4 +1,4 @@ -package osvrrendermanager; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_ViewportDescription.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_ViewportDescription.java similarity index 97% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_ViewportDescription.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_ViewportDescription.java index bb209c059..d9ff621be 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OSVR_ViewportDescription.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OSVR_ViewportDescription.java @@ -1,4 +1,4 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrrendermanageropengl/OsvrRenderManagerOpenGLLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OsvrRenderManagerOpenGLLibrary.java similarity index 79% rename from jme3-vr/src/main/java/osvrrendermanageropengl/OsvrRenderManagerOpenGLLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OsvrRenderManagerOpenGLLibrary.java index 08f3a2a27..2e706c31d 100644 --- a/jme3-vr/src/main/java/osvrrendermanageropengl/OsvrRenderManagerOpenGLLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrrendermanageropengl/OsvrRenderManagerOpenGLLibrary.java @@ -1,4 +1,5 @@ -package osvrrendermanageropengl; +package com.jme3.system.osvr.osvrrendermanageropengl; +import com.jme3.system.osvr.osvrclientkit.OsvrClientKitLibrary; import com.ochafik.lang.jnaerator.runtime.NativeSize; import com.ochafik.lang.jnaerator.runtime.NativeSizeByReference; import com.sun.jna.Library; @@ -13,7 +14,6 @@ import com.sun.jna.ptr.PointerByReference; import java.nio.DoubleBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; -import osvrclientkit.OsvrClientKitLibrary; /** * JNA Wrapper for library osvrRenderManagerOpenGL
* This file was autogenerated by JNAerator,
@@ -67,7 +67,7 @@ public class OsvrRenderManagerOpenGLLibrary implements Library { */ public static native byte osvrRenderManagerFinishRegisterRenderBuffers(Pointer renderManager, Pointer registerBufferState, byte appWillNotOverwriteBeforeNewPresent); /** Original signature : OSVR_ReturnCode osvrRenderManagerPresentSolidColorf(OSVR_RenderManager, OSVR_RGB_FLOAT) */ - public static native byte osvrRenderManagerPresentSolidColorf(Pointer renderManager, osvrrendermanageropengl.OSVR_RGB.ByValue rgb); + public static native byte osvrRenderManagerPresentSolidColorf(Pointer renderManager, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RGB.ByValue rgb); /** * when you're done.
* Original signature : OSVR_ReturnCode osvrRenderManagerGetRenderInfoCollection(OSVR_RenderManager, OSVR_RenderParams, OSVR_RenderInfoCollection*) @@ -86,55 +86,55 @@ public class OsvrRenderManagerOpenGLLibrary implements Library { /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_OpenGL(double*, OSVR_ProjectionMatrix)
- * @deprecated use the safer methods {@link #OSVR_Projection_to_OpenGL(java.nio.DoubleBuffer, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_OpenGL(com.sun.jna.ptr.DoubleByReference, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} instead + * @deprecated use the safer methods {@link #OSVR_Projection_to_OpenGL(java.nio.DoubleBuffer, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_OpenGL(com.sun.jna.ptr.DoubleByReference, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} instead */ @Deprecated - public static native byte OSVR_Projection_to_OpenGL(DoubleByReference OpenGL_out, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_OpenGL(DoubleByReference OpenGL_out, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_OpenGL(double*, OSVR_ProjectionMatrix) */ - public static native byte OSVR_Projection_to_OpenGL(DoubleBuffer OpenGL_out, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_OpenGL(DoubleBuffer OpenGL_out, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_D3D(float[16], OSVR_ProjectionMatrix)
- * @deprecated use the safer methods {@link #OSVR_Projection_to_D3D(java.nio.FloatBuffer, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_D3D(com.sun.jna.ptr.FloatByReference, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} instead + * @deprecated use the safer methods {@link #OSVR_Projection_to_D3D(java.nio.FloatBuffer, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_D3D(com.sun.jna.ptr.FloatByReference, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} instead */ @Deprecated - public static native byte OSVR_Projection_to_D3D(FloatByReference D3D_out, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_D3D(FloatByReference D3D_out, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_D3D(float[16], OSVR_ProjectionMatrix) */ - public static native byte OSVR_Projection_to_D3D(FloatBuffer D3D_out, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_D3D(FloatBuffer D3D_out, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_Unreal(float[16], OSVR_ProjectionMatrix)
- * @deprecated use the safer methods {@link #OSVR_Projection_to_Unreal(java.nio.FloatBuffer, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_Unreal(com.sun.jna.ptr.FloatByReference, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} instead + * @deprecated use the safer methods {@link #OSVR_Projection_to_Unreal(java.nio.FloatBuffer, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} and {@link #OSVR_Projection_to_Unreal(com.sun.jna.ptr.FloatByReference, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue)} instead */ @Deprecated - public static native byte OSVR_Projection_to_Unreal(FloatByReference Unreal_out, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_Unreal(FloatByReference Unreal_out, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); /** * @return True on success, false on failure (null pointer).
* Original signature : OSVR_ReturnCode OSVR_Projection_to_Unreal(float[16], OSVR_ProjectionMatrix) */ - public static native byte OSVR_Projection_to_Unreal(FloatBuffer Unreal_out, osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); + public static native byte OSVR_Projection_to_Unreal(FloatBuffer Unreal_out, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ProjectionMatrix.ByValue projection_in); /** * Original signature : OSVR_ReturnCode osvrCreateRenderManagerOpenGL(OSVR_ClientContext, const char[], OSVR_GraphicsLibraryOpenGL, OSVR_RenderManager*, OSVR_RenderManagerOpenGL*)
- * @deprecated use the safer methods {@link #osvrCreateRenderManagerOpenGL(osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary.OSVR_ClientContext, byte[], osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue, com.sun.jna.ptr.PointerByReference, com.sun.jna.ptr.PointerByReference)} and {@link #osvrCreateRenderManagerOpenGL(com.sun.jna.Pointer, com.sun.jna.Pointer, osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue, com.sun.jna.ptr.PointerByReference, com.sun.jna.ptr.PointerByReference)} instead + * @deprecated use the safer methods {@link #osvrCreateRenderManagerOpenGL(com.jme3.system.osvr.osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary.OSVR_ClientContext, byte[], com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue, com.sun.jna.ptr.PointerByReference, com.sun.jna.ptr.PointerByReference)} and {@link #osvrCreateRenderManagerOpenGL(com.sun.jna.Pointer, com.sun.jna.Pointer, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue, com.sun.jna.ptr.PointerByReference, com.sun.jna.ptr.PointerByReference)} instead */ @Deprecated - public static native byte osvrCreateRenderManagerOpenGL(Pointer clientContext, Pointer graphicsLibraryName, osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary, PointerByReference renderManagerOut, PointerByReference renderManagerOpenGLOut); + public static native byte osvrCreateRenderManagerOpenGL(Pointer clientContext, Pointer graphicsLibraryName, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary, PointerByReference renderManagerOut, PointerByReference renderManagerOpenGLOut); /** Original signature : OSVR_ReturnCode osvrCreateRenderManagerOpenGL(OSVR_ClientContext, const char[], OSVR_GraphicsLibraryOpenGL, OSVR_RenderManager*, OSVR_RenderManagerOpenGL*) */ - public static native byte osvrCreateRenderManagerOpenGL(OsvrClientKitLibrary.OSVR_ClientContext clientContext, byte graphicsLibraryName[], osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary, PointerByReference renderManagerOut, PointerByReference renderManagerOpenGLOut); + public static native byte osvrCreateRenderManagerOpenGL(OsvrClientKitLibrary.OSVR_ClientContext clientContext, byte graphicsLibraryName[], com.jme3.system.osvr.osvrrendermanageropengl.OSVR_GraphicsLibraryOpenGL.ByValue graphicsLibrary, PointerByReference renderManagerOut, PointerByReference renderManagerOpenGLOut); /** Original signature : OSVR_ReturnCode osvrRenderManagerGetRenderInfoOpenGL(OSVR_RenderManagerOpenGL, OSVR_RenderInfoCount, OSVR_RenderParams, OSVR_RenderInfoOpenGL*) */ public static native byte osvrRenderManagerGetRenderInfoOpenGL(Pointer renderManager, NativeSize renderInfoIndex, OSVR_RenderParams.ByValue renderParams, OSVR_RenderInfoOpenGL renderInfoOut); /** Original signature : OSVR_ReturnCode osvrRenderManagerOpenDisplayOpenGL(OSVR_RenderManagerOpenGL, OSVR_OpenResultsOpenGL*) */ public static native byte osvrRenderManagerOpenDisplayOpenGL(Pointer renderManager, OSVR_OpenResultsOpenGL openResultsOut); /** Original signature : OSVR_ReturnCode osvrRenderManagerPresentRenderBufferOpenGL(OSVR_RenderManagerPresentState, OSVR_RenderBufferOpenGL, OSVR_RenderInfoOpenGL, OSVR_ViewportDescription) */ - public static native byte osvrRenderManagerPresentRenderBufferOpenGL(Pointer presentState, osvrrendermanageropengl.OSVR_RenderBufferOpenGL.ByValue buffer, OSVR_RenderInfoOpenGL.ByValue renderInfoUsed, osvrrendermanageropengl.OSVR_ViewportDescription.ByValue normalizedCroppingViewport); + public static native byte osvrRenderManagerPresentRenderBufferOpenGL(Pointer presentState, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderBufferOpenGL.ByValue buffer, OSVR_RenderInfoOpenGL.ByValue renderInfoUsed, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ViewportDescription.ByValue normalizedCroppingViewport); /** Original signature : OSVR_ReturnCode osvrRenderManagerRegisterRenderBufferOpenGL(OSVR_RenderManagerRegisterBufferState, OSVR_RenderBufferOpenGL) */ - public static native byte osvrRenderManagerRegisterRenderBufferOpenGL(Pointer registerBufferState, osvrrendermanageropengl.OSVR_RenderBufferOpenGL.ByValue renderBuffer); + public static native byte osvrRenderManagerRegisterRenderBufferOpenGL(Pointer registerBufferState, com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderBufferOpenGL.ByValue renderBuffer); /** * Gets a given OSVR_RenderInfoOpenGL from an OSVR_RenderInfoCollection.
* Original signature : OSVR_ReturnCode osvrRenderManagerGetRenderInfoFromCollectionOpenGL(OSVR_RenderInfoCollection, OSVR_RenderInfoCount, OSVR_RenderInfoOpenGL*) diff --git a/jme3-vr/src/main/java/osvrtimevalue/OSVR_TimeValue.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrtimevalue/OSVR_TimeValue.java similarity index 96% rename from jme3-vr/src/main/java/osvrtimevalue/OSVR_TimeValue.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrtimevalue/OSVR_TimeValue.java index 61c111f3f..db60f043d 100644 --- a/jme3-vr/src/main/java/osvrtimevalue/OSVR_TimeValue.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrtimevalue/OSVR_TimeValue.java @@ -1,4 +1,4 @@ -package osvrtimevalue; +package com.jme3.system.osvr.osvrtimevalue; import com.sun.jna.Pointer; import com.sun.jna.Structure; import java.util.Arrays; diff --git a/jme3-vr/src/main/java/osvrtimevalue/OsvrTimeValueLibrary.java b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrtimevalue/OsvrTimeValueLibrary.java similarity index 99% rename from jme3-vr/src/main/java/osvrtimevalue/OsvrTimeValueLibrary.java rename to jme3-vr/src/main/java/com/jme3/system/osvr/osvrtimevalue/OsvrTimeValueLibrary.java index 6f9f2c0b2..886c16d8f 100644 --- a/jme3-vr/src/main/java/osvrtimevalue/OsvrTimeValueLibrary.java +++ b/jme3-vr/src/main/java/com/jme3/system/osvr/osvrtimevalue/OsvrTimeValueLibrary.java @@ -1,4 +1,4 @@ -package osvrtimevalue; +package com.jme3.system.osvr.osvrtimevalue; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; diff --git a/jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java b/jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java new file mode 100644 index 000000000..7a9b5ea56 --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/util/AbstractVRViewManager.java @@ -0,0 +1,223 @@ +package com.jme3.util; + +import com.jme3.app.VREnvironment; +import com.jme3.post.CartoonSSAO; +import com.jme3.post.Filter; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.FilterUtil; +import com.jme3.post.SceneProcessor; +import com.jme3.post.filters.FogFilter; +import com.jme3.post.filters.TranslucentBucketFilter; +import com.jme3.post.ssao.SSAOFilter; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.shadow.DirectionalLightShadowFilter; +import com.jme3.shadow.VRDirectionalLightShadowRenderer; +import com.jme3.texture.Texture2D; + +/** + * A VR view manager. This class holds methods that enable to submit 3D views to the VR compositor. + * System dependent classes should extends from this one. + * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + */ +public abstract class AbstractVRViewManager implements VRViewManager { + + + //private static final Logger logger = Logger.getLogger(AbstractVRViewManager.class.getName()); + + protected VREnvironment environment = null; + + protected Camera leftCamera; + protected ViewPort leftViewport; + protected FilterPostProcessor leftPostProcessor; + protected Texture2D leftEyeTexture; + protected Texture2D leftEyeDepth; + + protected Camera rightCamera; + protected ViewPort rightViewport; + protected FilterPostProcessor rightPostProcessor; + protected Texture2D rightEyeTexture; + protected Texture2D rightEyeDepth; + + private float resMult = 1f; + + private float heightAdjustment; + + @Override + public Camera getLeftCamera() { + return leftCamera; + } + + @Override + public Camera getRightCamera() { + return rightCamera; + } + + @Override + public ViewPort getLeftViewport() { + return leftViewport; + } + + @Override + public ViewPort getRightViewport() { + return rightViewport; + } + + @Override + public Texture2D getLeftTexture(){ + return leftEyeTexture; + } + + @Override + public Texture2D getRightTexture(){ + return rightEyeTexture; + } + + @Override + public Texture2D getLeftDepth(){ + return leftEyeDepth; + } + + @Override + public Texture2D getRightDepth(){ + return rightEyeDepth; + } + + @Override + public FilterPostProcessor getLeftPostProcessor(){ + return leftPostProcessor; + } + + @Override + public FilterPostProcessor getRightPostProcessor(){ + return rightPostProcessor; + } + + @Override + public float getResolutionMuliplier() { + return resMult; + } + + @Override + public void setResolutionMultiplier(float resMult) { + this.resMult = resMult; + } + + @Override + public float getHeightAdjustment() { + return heightAdjustment; + } + + @Override + public void setHeightAdjustment(float amount) { + heightAdjustment = amount; + } + + @Override + public VREnvironment getVREnvironment(){ + return environment; + } + + /** + * Handles moving filters from the main view to each eye + */ + public void moveScreenProcessingToEyes() { + + if (environment != null){ + if( getRightViewport() == null ){ + return; + } + + if (environment.getApplication() != null){ + syncScreenProcessing(environment.getApplication().getViewPort()); + environment.getApplication().getViewPort().clearProcessors(); + } else { + throw new IllegalStateException("The VR environment is not attached to any application."); + } + + + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + + + } + + /** + * Sets the two views to use the list of {@link SceneProcessor processors}. + * @param sourceViewport the {@link ViewPort viewport} that contains the processors to use. + */ + public void syncScreenProcessing(ViewPort sourceViewport) { + + if (environment != null){ + if( getRightViewport() == null ){ + return; + } + + if (environment.getApplication() != null){ + // setup post processing filters + if( getRightPostProcessor() == null ) { + rightPostProcessor = new FilterPostProcessor(environment.getApplication().getAssetManager()); + leftPostProcessor = new FilterPostProcessor(environment.getApplication().getAssetManager()); + } + // clear out all filters & processors, to start from scratch + getRightPostProcessor().removeAllFilters(); + getLeftPostProcessor().removeAllFilters(); + getLeftViewport().clearProcessors(); + getRightViewport().clearProcessors(); + // if we have no processors to sync, don't add the FilterPostProcessor + if( sourceViewport.getProcessors().isEmpty() ) return; + // add post processors we just made, which are empty + getLeftViewport().addProcessor(getLeftPostProcessor()); + getRightViewport().addProcessor(getRightPostProcessor()); + // go through all of the filters in the processors list + // add them to the left viewport processor & clone them to the right + for(SceneProcessor sceneProcessor : sourceViewport.getProcessors()) { + if (sceneProcessor instanceof FilterPostProcessor) { + for(Filter f : ((FilterPostProcessor)sceneProcessor).getFilterList() ) { + if( f instanceof TranslucentBucketFilter ) { + // just remove this filter, we will add it at the end manually + ((FilterPostProcessor)sceneProcessor).removeFilter(f); + } else { + getLeftPostProcessor().addFilter(f); + // clone to the right + Filter f2; + if(f instanceof FogFilter){ + f2 = FilterUtil.cloneFogFilter((FogFilter)f); + } else if (f instanceof CartoonSSAO ) { + f2 = new CartoonSSAO((CartoonSSAO)f); + } else if (f instanceof SSAOFilter){ + f2 = FilterUtil.cloneSSAOFilter((SSAOFilter)f); + } else if (f instanceof DirectionalLightShadowFilter){ + f2 = FilterUtil.cloneDirectionalLightShadowFilter(environment.getApplication().getAssetManager(), (DirectionalLightShadowFilter)f); + } else { + f2 = f; // dof, bloom, lightscattering etc. + } + getRightPostProcessor().addFilter(f2); + } + } + } else if (sceneProcessor instanceof VRDirectionalLightShadowRenderer) { + // shadow processing + // TODO: make right shadow processor use same left shadow maps for performance + VRDirectionalLightShadowRenderer dlsr = (VRDirectionalLightShadowRenderer) sceneProcessor; + VRDirectionalLightShadowRenderer dlsrRight = dlsr.clone(); + dlsrRight.setLight(dlsr.getLight()); + getRightViewport().getProcessors().add(0, dlsrRight); + getLeftViewport().getProcessors().add(0, sceneProcessor); + } + } + // make sure each has a translucent filter renderer + getLeftPostProcessor().addFilter(new TranslucentBucketFilter()); + getRightPostProcessor().addFilter(new TranslucentBucketFilter()); + } else { + throw new IllegalStateException("The VR environment is not attached to any application."); + } + + + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + + + } +} diff --git a/jme3-vr/src/main/java/com/jme3/util/VRGUIPositioningMode.java b/jme3-vr/src/main/java/com/jme3/util/VRGUIPositioningMode.java new file mode 100644 index 000000000..a7b8642f0 --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/util/VRGUIPositioningMode.java @@ -0,0 +1,15 @@ +package com.jme3.util; + +/** + * A enumeration that describes the GUI display positioning modes. + * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + * + */ +public enum VRGUIPositioningMode { + MANUAL, + AUTO_CAM_ALL, + AUTO_CAM_ALL_SKIP_PITCH, + AUTO_OBSERVER_POS_CAM_ROTATION, + AUTO_OBSERVER_ALL, + AUTO_OBSERVER_ALL_CAMHEIGHT +} diff --git a/jme3-vr/src/main/java/com/jme3/util/VRGuiManager.java b/jme3-vr/src/main/java/com/jme3/util/VRGuiManager.java new file mode 100644 index 000000000..46b3dbbb6 --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/util/VRGuiManager.java @@ -0,0 +1,474 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.util; + +import com.jme3.app.VREnvironment; +import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Matrix3f; +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.renderer.queue.RenderQueue.Bucket; +import com.jme3.scene.Spatial; +import com.jme3.scene.CenterQuad; +import com.jme3.scene.Geometry; +import com.jme3.scene.Node; +import com.jme3.system.AppSettings; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import java.awt.GraphicsEnvironment; +import java.util.Iterator; + +/** + * A class dedicated to the management and the display of a Graphical User Interface (GUI) within a VR environment. + * @author reden - phr00t - https://github.com/phr00t + * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + * + */ +public class VRGuiManager { + + private Camera camLeft, camRight; + private float guiDistance = 1.5f; + private float guiScale = 1f; + private float guiPositioningElastic; + + private VRGUIPositioningMode posMode = VRGUIPositioningMode.AUTO_CAM_ALL; + + private final Matrix3f orient = new Matrix3f(); + private Vector2f screenSize; + protected boolean wantsReposition; + + private Vector2f ratio; + + private final Vector3f EoldPos = new Vector3f(); + + private final Quaternion EoldDir = new Quaternion(); + + private final Vector3f look = new Vector3f(); + private final Vector3f left = new Vector3f(); + private final Vector3f temppos = new Vector3f(); + private final Vector3f up = new Vector3f(); + + private boolean useCurvedSurface = false; + private boolean overdraw = false; + private Geometry guiQuad; + private Node guiQuadNode; + private ViewPort offView; + private Texture2D guiTexture; + + private final Quaternion tempq = new Quaternion(); + + private VREnvironment environment = null; + + /** + * Create a new GUI manager attached to the given app state. + * @param environment the VR environment to which this manager is attached to. + */ + public VRGuiManager(VREnvironment environment){ + this.environment = environment; + } + + /** + * + * Makes auto GUI positioning happen not immediately, but like an + * elastic connected to the headset. Setting to 0 disables (default) + * Higher settings make it track the headset quicker. + * + * @param elastic amount of elasticity + */ + public void setPositioningElasticity(float elastic) { + guiPositioningElastic = elastic; + } + + public float getPositioningElasticity() { + return guiPositioningElastic; + } + + /** + * Get the GUI {@link VRGUIPositioningMode positioning mode}. + * @return the GUI {@link VRGUIPositioningMode positioning mode}. + * @see #setPositioningMode(VRGUIPositioningMode) + */ + public VRGUIPositioningMode getPositioningMode() { + return posMode; + } + + /** + * Set the GUI {@link VRGUIPositioningMode positioning mode}. + * @param mode the GUI {@link VRGUIPositioningMode positioning mode}. + * @see #getPositioningMode() + */ + public void setPositioningMode(VRGUIPositioningMode mode) { + posMode = mode; + } + + /** + * Get the GUI canvas size. This method return the size in pixels of the GUI available area within the VR view. + * @return the GUI canvas size. This method return the size in pixels of the GUI available area within the VR view. + */ + public Vector2f getCanvasSize() { + + if (environment != null){ + + if (environment.getApplication() != null){ + if( screenSize == null ) { + if( environment.isInVR() && environment.getVRHardware() != null ) { + screenSize = new Vector2f(); + environment.getVRHardware().getRenderSize(screenSize); + screenSize.multLocal(environment.getVRViewManager().getResolutionMuliplier()); + } else { + AppSettings as = environment.getApplication().getContext().getSettings(); + screenSize = new Vector2f(as.getWidth(), as.getHeight()); + } + } + return screenSize; + } else { + throw new IllegalStateException("VR GUI manager underlying environment is not attached to any application."); + } + } else { + throw new IllegalStateException("VR GUI manager is not attached to any environment."); + } + + } + + /** + * Get the ratio between the {@link #getCanvasSize() GUI canvas size} and the application main windows (if available) or the screen size. + * @return the ratio between the {@link #getCanvasSize() GUI canvas size} and the application main windows (if available). + * @see #getCanvasSize() + */ + public Vector2f getCanvasToWindowRatio() { + + if (environment != null){ + + if (environment.getApplication() != null){ + if( ratio == null ) { + ratio = new Vector2f(); + Vector2f canvas = getCanvasSize(); + int width = Integer.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getWidth(), + environment.getApplication().getContext().getSettings().getWidth()); + int height = Integer.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getHeight(), + environment.getApplication().getContext().getSettings().getHeight()); + ratio.x = Float.max(1f, canvas.x / width); + ratio.y = Float.max(1f, canvas.y / height); + } + return ratio; + + } else { + throw new IllegalStateException("VR GUI manager underlying environment is not attached to any application."); + } + } else { + throw new IllegalStateException("VR GUI manager is not attached to any environment."); + } + } + + /** + * Inform this manager that it has to position the GUI. + */ + public void positionGui() { + wantsReposition = true; + } + + /** + * Position the GUI to the given location. + * @param pos the position of the GUI. + * @param dir the rotation of the GUI. + * @param tpf the time per frame. + */ + private void positionTo(Vector3f pos, Quaternion dir, float tpf) { + + if (environment != null){ + Vector3f guiPos = guiQuadNode.getLocalTranslation(); + guiPos.set(0f, 0f, guiDistance); + dir.mult(guiPos, guiPos); + guiPos.x += pos.x; + guiPos.y += pos.y + environment.getVRHeightAdjustment(); + guiPos.z += pos.z; + if( guiPositioningElastic > 0f && posMode != VRGUIPositioningMode.MANUAL ) { + // mix pos & dir with current pos & dir + guiPos.interpolateLocal(EoldPos, guiPos, Float.min(1f, tpf * guiPositioningElastic)); + EoldPos.set(guiPos); + } + } else { + throw new IllegalStateException("VR GUI manager is not attached to any environment."); + } + } + + /** + * Update the GUI geometric state. This method should be called after GUI modification. + */ + protected void updateGuiQuadGeometricState() { + guiQuadNode.updateGeometricState(); + } + + /** + * Position the GUI without delay. + * @param tpf the time per frame. + */ + protected void positionGuiNow(float tpf) { + + if (environment != null){ + wantsReposition = false; + if( environment.isInVR() == false ){ + return; + } + + guiQuadNode.setLocalScale(guiDistance * guiScale * 4f, 4f * guiDistance * guiScale, 1f); + + switch( posMode ) { + case MANUAL: + case AUTO_CAM_ALL_SKIP_PITCH: + case AUTO_CAM_ALL: + if( camLeft != null && camRight != null ) { + // get middle point + temppos.set(camLeft.getLocation()).interpolateLocal(camRight.getLocation(), 0.5f); + positionTo(temppos, camLeft.getRotation(), tpf); + } + rotateScreenTo(camLeft.getRotation(), tpf); + + break; + case AUTO_OBSERVER_POS_CAM_ROTATION: + Object obs = environment.getObserver(); + if( obs != null ) { + if( obs instanceof Camera ) { + positionTo(((Camera)obs).getLocation(), camLeft.getRotation(), tpf); + } else { + positionTo(((Spatial)obs).getWorldTranslation(), camLeft.getRotation(), tpf); + } + } + rotateScreenTo(camLeft.getRotation(), tpf); + + break; + case AUTO_OBSERVER_ALL: + case AUTO_OBSERVER_ALL_CAMHEIGHT: + obs = environment.getObserver(); + if( obs != null ) { + Quaternion q; + if( obs instanceof Camera ) { + q = ((Camera)obs).getRotation(); + temppos.set(((Camera)obs).getLocation()); + } else { + q = ((Spatial)obs).getWorldRotation(); + temppos.set(((Spatial)obs).getWorldTranslation()); + } + if( posMode == VRGUIPositioningMode.AUTO_OBSERVER_ALL_CAMHEIGHT ) { + temppos.y = camLeft.getLocation().y; + } + positionTo(temppos, q, tpf); + rotateScreenTo(q, tpf); + + } + break; + } + } else { + throw new IllegalStateException("VR GUI manager is not attached to any environment."); + } + } + + /** + * Rotate the GUI to the given direction. + * @param dir the direction to rotate to. + * @param tpf the time per frame. + */ + private void rotateScreenTo(Quaternion dir, float tpf) { + dir.getRotationColumn(2, look).negateLocal(); + dir.getRotationColumn(0, left).negateLocal(); + orient.fromAxes(left, dir.getRotationColumn(1, up), look); + Quaternion rot = tempq.fromRotationMatrix(orient); + if( posMode == VRGUIPositioningMode.AUTO_CAM_ALL_SKIP_PITCH ){ + VRUtil.stripToYaw(rot); + } + + if( guiPositioningElastic > 0f && posMode != VRGUIPositioningMode.MANUAL ) { + // mix pos & dir with current pos & dir + EoldDir.nlerp(rot, tpf * guiPositioningElastic); + guiQuadNode.setLocalRotation(EoldDir); + } else { + guiQuadNode.setLocalRotation(rot); + } + } + + /** + * Get the GUI distance from the observer. + * @return the GUI distance from the observer. + * @see #setGuiDistance(float) + */ + public float getGuiDistance() { + return guiDistance; + } + + /** + * Set the GUI distance from the observer. + * @param newGuiDistance the GUI distance from the observer. + * @see #getGuiDistance() + */ + public void setGuiDistance(float newGuiDistance) { + guiDistance = newGuiDistance; + } + + /** + * Get the GUI scale. + * @return the GUI scale. + * @see #setGuiScale(float) + */ + public float getGUIScale(){ + return guiScale; + } + + /** + * Set the GUI scale. + * @param scale the GUI scale. + * @see #getGUIScale() + */ + public void setGuiScale(float scale) { + guiScale = scale; + } + + /** + * Adjust the GUI distance from the observer. + * This method increment / decrement the {@link #getGuiDistance() GUI distance} by the given value. + * @param adjustAmount the increment (if positive) / decrement (if negative) value of the GUI distance. + */ + public void adjustGuiDistance(float adjustAmount) { + guiDistance += adjustAmount; + } + + /** + * Set up the GUI. + * @param leftcam the left eye camera. + * @param rightcam the right eye camera. + * @param left the left eye viewport. + * @param right the right eye viewport. + */ + protected void setupGui(Camera leftcam, Camera rightcam, ViewPort left, ViewPort right) { + + if (environment != null){ + if( environment.hasTraditionalGUIOverlay() ) { + camLeft = leftcam; + camRight = rightcam; + Spatial guiScene = getGuiQuad(camLeft); + left.attachScene(guiScene); + if( right != null ) right.attachScene(guiScene); + setPositioningMode(posMode); + } + } else { + throw new IllegalStateException("VR GUI manager is not attached to any environment."); + } + } + + /** + * Get if the GUI has to use curved surface. + * @return true if the GUI has to use curved surface and false otherwise. + * @see #setCurvedSurface(boolean) + */ + public boolean isCurverSurface(){ + return useCurvedSurface; + } + + /** + * Set if the GUI has to use curved surface. + * @param set true if the GUI has to use curved surface and false otherwise. + * @see #isCurverSurface() + */ + public void setCurvedSurface(boolean set) { + useCurvedSurface = set; + } + + /** + * Get if the GUI has to be displayed even if it is behind objects. + * @return true if the GUI has to use curved surface and false otherwise. + * @see #setGuiOverdraw(boolean) + */ + public boolean isGuiOverdraw(){ + return overdraw; + } + + /** + * Set if the GUI has to be displayed even if it is behind objects. + * @param set true if the GUI has to use curved surface and false otherwise. + * @see #isGuiOverdraw() + */ + public void setGuiOverdraw(boolean set) { + overdraw = set; + } + + /** + * Create a GUI quad for the given camera. + * @param sourceCam the camera + * @return a GUI quad for the given camera. + */ + private Spatial getGuiQuad(Camera sourceCam){ + + if (environment != null){ + + if (environment.getApplication() != null){ + if( guiQuadNode == null ) { + Vector2f guiCanvasSize = getCanvasSize(); + Camera offCamera = sourceCam.clone(); + offCamera.setParallelProjection(true); + offCamera.setLocation(Vector3f.ZERO); + offCamera.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y); + + offView = environment.getApplication().getRenderManager().createPreView("GUI View", offCamera); + offView.setClearFlags(true, true, true); + offView.setBackgroundColor(ColorRGBA.BlackNoAlpha); + + // create offscreen framebuffer + FrameBuffer offBuffer = new FrameBuffer((int)guiCanvasSize.x, (int)guiCanvasSize.y, 1); + + //setup framebuffer's texture + guiTexture = new Texture2D((int)guiCanvasSize.x, (int)guiCanvasSize.y, Format.RGBA8); + guiTexture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); + guiTexture.setMagFilter(Texture.MagFilter.Bilinear); + + //setup framebuffer to use texture + offBuffer.setDepthBuffer(Format.Depth); + offBuffer.setColorTexture(guiTexture); + + //set viewport to render to offscreen framebuffer + offView.setOutputFrameBuffer(offBuffer); + + // setup framebuffer's scene + Iterator spatialIter = environment.getApplication().getGuiViewPort().getScenes().iterator(); + while(spatialIter.hasNext()){ + offView.attachScene(spatialIter.next()); + } + + + if( useCurvedSurface ) { + guiQuad = (Geometry)environment.getApplication().getAssetManager().loadModel("Common/Util/gui_mesh.j3o"); + } else { + guiQuad = new Geometry("guiQuad", new CenterQuad(1f, 1f)); + } + + Material mat = new Material(environment.getApplication().getAssetManager(), "Common/MatDefs/VR/GuiOverlay.j3md"); + mat.getAdditionalRenderState().setDepthTest(!overdraw); + mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); + mat.getAdditionalRenderState().setDepthWrite(false); + mat.setTexture("ColorMap", guiTexture); + guiQuad.setQueueBucket(Bucket.Translucent); + guiQuad.setMaterial(mat); + + guiQuadNode = new Node("gui-quad-node"); + guiQuadNode.setQueueBucket(Bucket.Translucent); + guiQuadNode.attachChild(guiQuad); + } + return guiQuadNode; + } else { + throw new IllegalStateException("VR GUI manager underlying environment is not attached to any application."); + } + } else { + throw new IllegalStateException("VR GUI manager is not attached to any environment."); + } + + + + } +} diff --git a/jme3-vr/src/main/java/com/jme3/util/VRMouseManager.java b/jme3-vr/src/main/java/com/jme3/util/VRMouseManager.java new file mode 100644 index 000000000..32eaca069 --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/util/VRMouseManager.java @@ -0,0 +1,334 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.util; + +import java.util.logging.Logger; + +import org.lwjgl.glfw.GLFW; + +import com.jme3.app.VREnvironment; +import com.jme3.input.MouseInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.lwjgl.GlfwMouseInputVR; +import com.jme3.input.vr.VRInputType; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.Vector2f; +import com.jme3.scene.Node; +import com.jme3.system.AppSettings; +import com.jme3.system.lwjgl.LwjglWindow; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import com.jme3.ui.Picture; + +/** + * A class dedicated to the handling of the mouse within VR environment. + * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + * + */ +public class VRMouseManager { + + private static final Logger logger = Logger.getLogger(VRMouseManager.class.getName()); + + + private VREnvironment environment = null; + + private final int AVERAGE_AMNT = 4; + private int avgCounter; + + private Picture mouseImage; + private int recentCenterCount = 0; + private final Vector2f cursorPos = new Vector2f(); + private float ySize, sensitivity = 8f, acceleration = 2f; + private final float[] lastXmv = new float[AVERAGE_AMNT], lastYmv = new float[AVERAGE_AMNT]; + private boolean thumbstickMode; + private float moveScale = 1f; + + private float avg(float[] arr) { + float amt = 0f; + for(float f : arr) amt += f; + return amt / arr.length; + } + + /** + * Create a new VR mouse manager within the given {@link VREnvironment VR environment}. + * @param environment the VR environment of the mouse manager. + */ + public VRMouseManager(VREnvironment environment){ + this.environment = environment; + } + + /** + * Initialize the VR mouse manager. + */ + protected void initialize() { + + logger.config("Initializing VR mouse manager."); + + // load default mouseimage + mouseImage = new Picture("mouse"); + setImage("Common/Util/mouse.png"); + // hide default cursor by making it invisible + + MouseInput mi = environment.getApplication().getContext().getMouseInput(); + if( mi instanceof GlfwMouseInputVR ){ + ((GlfwMouseInputVR)mi).hideActiveCursor(); + } + centerMouse(); + + logger.config("Initialized VR mouse manager [SUCCESS]"); + } + + public void setThumbstickMode(boolean set) { + thumbstickMode = set; + } + + public boolean isThumbstickMode() { + return thumbstickMode; + } + + /** + * Set the speed of the mouse. + * @param sensitivity the sensitivity of the mouse. + * @param acceleration the acceleration of the mouse. + * @see #getSpeedAcceleration() + * @see #getSpeedSensitivity() + */ + public void setSpeed(float sensitivity, float acceleration) { + this.sensitivity = sensitivity; + this.acceleration = acceleration; + } + + /** + * Get the sensitivity of the mouse. + * @return the sensitivity of the mouse. + * @see #setSpeed(float, float) + */ + public float getSpeedSensitivity() { + return sensitivity; + } + + /** + * Get the acceleration of the mouse. + * @return the acceleration of the mouse. + * @see #setSpeed(float, float) + */ + public float getSpeedAcceleration() { + return acceleration; + } + + /** + * Set the mouse move scale. + * @param set the mouse move scale. + */ + public void setMouseMoveScale(float set) { + moveScale = set; + } + + /** + * Set the image to use as mouse cursor. The given string describe an asset that the underlying application asset manager has to load. + * @param texture the image to use as mouse cursor. + */ + public void setImage(String texture) { + + if (environment != null){ + + if (environment.getApplication() != null){ + if( environment.isInVR() == false ){ + Texture tex = environment.getApplication().getAssetManager().loadTexture(texture); + mouseImage.setTexture(environment.getApplication().getAssetManager(), (Texture2D)tex, true); + ySize = tex.getImage().getHeight(); + mouseImage.setHeight(ySize); + mouseImage.setWidth(tex.getImage().getWidth()); + mouseImage.getMaterial().getAdditionalRenderState().setBlendMode(BlendMode.Alpha); + mouseImage.getMaterial().getAdditionalRenderState().setDepthWrite(false); + } else { + Texture tex = environment.getApplication().getAssetManager().loadTexture(texture); + mouseImage.setTexture(environment.getApplication().getAssetManager(), (Texture2D)tex, true); + ySize = tex.getImage().getHeight(); + mouseImage.setHeight(ySize); + mouseImage.setWidth(tex.getImage().getWidth()); + mouseImage.getMaterial().getAdditionalRenderState().setBlendMode(BlendMode.Alpha); + mouseImage.getMaterial().getAdditionalRenderState().setDepthWrite(false); + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Update analog controller as it was a mouse controller. + * @param inputIndex the index of the controller attached to the VR system. + * @param mouseListener the JMonkey mouse listener to trigger. + * @param mouseXName the mouseX identifier. + * @param mouseYName the mouseY identifier + * @param tpf the time per frame. + */ + public void updateAnalogAsMouse(int inputIndex, AnalogListener mouseListener, String mouseXName, String mouseYName, float tpf) { + + if (environment != null){ + if (environment.getApplication() != null){ + // got a tracked controller to use as the "mouse" + if( environment.isInVR() == false || + environment.getVRinput() == null || + environment.getVRinput().isInputDeviceTracking(inputIndex) == false ){ + return; + } + + Vector2f tpDelta; + if( thumbstickMode ) { + tpDelta = environment.getVRinput().getAxis(inputIndex, VRInputType.ViveTrackpadAxis); + } else { + tpDelta = environment.getVRinput().getAxisDeltaSinceLastCall(inputIndex, VRInputType.ViveTrackpadAxis); + } + + float Xamount = (float)Math.pow(Math.abs(tpDelta.x) * sensitivity, acceleration); + float Yamount = (float)Math.pow(Math.abs(tpDelta.y) * sensitivity, acceleration); + + if( tpDelta.x < 0f ){ + Xamount = -Xamount; + } + + if( tpDelta.y < 0f ){ + Yamount = -Yamount; + } + + Xamount *= moveScale; Yamount *= moveScale; + if( mouseListener != null ) { + if( tpDelta.x != 0f && mouseXName != null ) mouseListener.onAnalog(mouseXName, Xamount * 0.2f, tpf); + if( tpDelta.y != 0f && mouseYName != null ) mouseListener.onAnalog(mouseYName, Yamount * 0.2f, tpf); + } + + if( environment.getApplication().getInputManager().isCursorVisible() ) { + int index = (avgCounter+1) % AVERAGE_AMNT; + lastXmv[index] = Xamount * 133f; + lastYmv[index] = Yamount * 133f; + cursorPos.x -= avg(lastXmv); + cursorPos.y -= avg(lastYmv); + Vector2f maxsize = environment.getVRGUIManager().getCanvasSize(); + + if( cursorPos.x > maxsize.x ){ + cursorPos.x = maxsize.x; + } + + if( cursorPos.x < 0f ){ + cursorPos.x = 0f; + } + + if( cursorPos.y > maxsize.y ){ + cursorPos.y = maxsize.y; + } + + if( cursorPos.y < 0f ){ + cursorPos.y = 0f; + } + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Get the actual cursor position. + * @return the actual cursor position. + */ + public Vector2f getCursorPosition() { + + if (environment != null){ + if (environment.getApplication() != null){ + if( environment.isInVR() ) { + return cursorPos; + } + + return environment.getApplication().getInputManager().getCursorPosition(); + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Center the mouse on the display. + */ + public void centerMouse() { + + if (environment != null){ + if (environment.getApplication() != null){ + // set mouse in center of the screen if newly added + Vector2f size = environment.getVRGUIManager().getCanvasSize(); + MouseInput mi = environment.getApplication().getContext().getMouseInput(); + AppSettings as = environment.getApplication().getContext().getSettings(); + if( mi instanceof GlfwMouseInputVR ) ((GlfwMouseInputVR)mi).setCursorPosition((int)(as.getWidth() / 2f), (int)(as.getHeight() / 2f)); + if( environment.isInVR() ) { + cursorPos.x = size.x / 2f; + cursorPos.y = size.y / 2f; + recentCenterCount = 2; + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + + } + + /** + * Update the mouse manager. This method should not be called manually. + * The standard behavior for this method is to be called from the {@link VRViewManager#update(float) update method} of the attached {@link VRViewManager VR view manager}. + * @param tpf the time per frame. + */ + protected void update(float tpf) { + // if we are showing the cursor, add our picture as it + + if( environment.getApplication().getInputManager().isCursorVisible() ) { + if( mouseImage.getParent() == null ) { + + environment.getApplication().getGuiViewPort().attachScene(mouseImage); + centerMouse(); + // the "real" mouse pointer should stay hidden + if (environment.getApplication().getContext() instanceof LwjglWindow){ + GLFW.glfwSetInputMode(((LwjglWindow)environment.getApplication().getContext()).getWindowHandle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED); + } + } + // handle mouse movements, which may be in addition to (or exclusive from) tracked movement + MouseInput mi = environment.getApplication().getContext().getMouseInput(); + if( mi instanceof GlfwMouseInputVR ) { + if( recentCenterCount <= 0 ) { + //Vector2f winratio = VRGuiManager.getCanvasToWindowRatio(); + cursorPos.x += ((GlfwMouseInputVR)mi).getLastDeltaX();// * winratio.x; + cursorPos.y += ((GlfwMouseInputVR)mi).getLastDeltaY();// * winratio.y; + if( cursorPos.x < 0f ) cursorPos.x = 0f; + if( cursorPos.y < 0f ) cursorPos.y = 0f; + if( cursorPos.x > environment.getVRGUIManager().getCanvasSize().x ) cursorPos.x = environment.getVRGUIManager().getCanvasSize().x; + if( cursorPos.y > environment.getVRGUIManager().getCanvasSize().y ) cursorPos.y = environment.getVRGUIManager().getCanvasSize().y; + } else recentCenterCount--; + ((GlfwMouseInputVR)mi).clearDeltas(); + } + // ok, update the cursor graphic position + Vector2f currentPos = getCursorPosition(); + mouseImage.setLocalTranslation(currentPos.x, currentPos.y - ySize, environment.getVRGUIManager().getGuiDistance() + 1f); + + mouseImage.updateGeometricState(); + + } else if( mouseImage.getParent() != null ) { + Node n = mouseImage.getParent(); + mouseImage.removeFromParent(); + + if (n != null){ + n.updateGeometricState(); + } + } + } +} diff --git a/jme3-vr/src/main/java/jmevr/util/VRUtil.java b/jme3-vr/src/main/java/com/jme3/util/VRUtil.java similarity index 98% rename from jme3-vr/src/main/java/jmevr/util/VRUtil.java rename to jme3-vr/src/main/java/com/jme3/util/VRUtil.java index 819baa04b..37de4a2b8 100644 --- a/jme3-vr/src/main/java/jmevr/util/VRUtil.java +++ b/jme3-vr/src/main/java/com/jme3/util/VRUtil.java @@ -2,7 +2,7 @@ * To change this template, choose Tools | Templates * and open the template in the editor. */ -package jmevr.util; +package com.jme3.util; import com.jme3.math.FastMath; import com.jme3.math.Matrix4f; @@ -12,10 +12,7 @@ import com.jme3.system.jopenvr.HmdMatrix44_t; import java.util.concurrent.TimeUnit; -/** - * - * @author reden - */ + public class VRUtil { private static final long SLEEP_PRECISION = TimeUnit.MILLISECONDS.toNanos(4); diff --git a/jme3-vr/src/main/java/com/jme3/util/VRViewManager.java b/jme3-vr/src/main/java/com/jme3/util/VRViewManager.java new file mode 100644 index 000000000..e2c503006 --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/util/VRViewManager.java @@ -0,0 +1,156 @@ +package com.jme3.util; + +import com.jme3.app.VRAppState; +import com.jme3.app.VREnvironment; +import com.jme3.app.state.AppState; +import com.jme3.post.FilterPostProcessor; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.texture.Texture2D; + +/** + * A VR view manager. This interface describes methods that enable to submit 3D views to the VR compositor. + * @author reden - phr00t - https://github.com/phr00t + * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + */ +public interface VRViewManager { + + /** + * The name of the left view. + */ + public final static String LEFT_VIEW_NAME = "Left View"; + + /** + * The name of the right view. + */ + public final static String RIGHT_VIEW_NAME = "Right View"; + + /** + * Get the {@link Camera camera} attached to the left eye. + * @return the {@link Camera camera} attached to the left eye. + * @see #getRightCamera() + */ + public Camera getLeftCamera(); + + /** + * Get the {@link Camera camera} attached to the right eye. + * @return the {@link Camera camera} attached to the right eye. + * @see #getLeftCamera() + */ + public Camera getRightCamera(); + + /** + * Get the {@link ViewPort viewport} attached to the left eye. + * @return the {@link ViewPort viewport} attached to the left eye. + * @see #getRightViewport() + */ + public ViewPort getLeftViewport(); + + + /** + * Get the {@link ViewPort viewport} attached to the right eye. + * @return the {@link ViewPort viewport} attached to the right eye. + * @see #getLeftViewport() + */ + public ViewPort getRightViewport(); + + /** + * Get the texture attached to the left eye. + * @return the texture attached to the left eye. + * @see #getRightTexture() + */ + public Texture2D getLeftTexture(); + + /** + * Get the texture attached to the right eye. + * @return the texture attached to the right eye. + * @see #getLeftTexture() + */ + public Texture2D getRightTexture(); + + /** + * Get the depth texture attached to the left eye. + * @return the texture attached to the left eye. + * @see #getRightTexture() + */ + public Texture2D getLeftDepth(); + + /** + * Get the depth texture attached to the right eye. + * @return the texture attached to the right eye. + * @see #getLeftTexture() + */ + public Texture2D getRightDepth(); + + /** + * Get the {@link FilterPostProcessor filter post processor} attached to the left eye. + * @return the {@link FilterPostProcessor filter post processor} attached to the left eye. + * @see #getRightPostProcessor() + */ + public FilterPostProcessor getLeftPostProcessor(); + + /** + * Get the {@link FilterPostProcessor filter post processor} attached to the right eye. + * @return the {@link FilterPostProcessor filter post processor} attached to the right eye. + * @see #getLeftPostProcessor() + */ + public FilterPostProcessor getRightPostProcessor(); + + /** + * Get the resolution multiplier. + * @return the resolution multiplier. + * @see #setResolutionMultiplier(float) + */ + public float getResolutionMuliplier(); + + /** + * Set the resolution multiplier. + * @param resMult the resolution multiplier. + * @see #getResolutionMuliplier() + */ + public void setResolutionMultiplier(float resMult); + + /** + * Get the height adjustment to apply to the cameras before rendering. + * @return the height adjustment to apply to the cameras before rendering. + * @see #setHeightAdjustment(float) + */ + public float getHeightAdjustment(); + + /** + * Set the height adjustment to apply to the cameras before rendering. + * @param amount the height adjustment to apply to the cameras before rendering. + * @see #getHeightAdjustment() + */ + public void setHeightAdjustment(float amount); + + /** + * Get the {@link VREnvironment VR environment} to which the view manager is attached. + * @return the {@link VREnvironment VR environment} to which the view manager is attached. + */ + public VREnvironment getVREnvironment(); + + /** + * Initialize the VR view manager. This method should be called after the attachment of a {@link VREnvironment VR environment} to an application. + */ + public void initialize(); + + /** + * Update the VR view manager. + * This method is called by the attached {@link VRAppState app state} and should not be called manually. + * @param tpf the time per frame. + */ + public void update(float tpf); + + /** + * Send the rendering result as textures to the two eyes. + * This method should be called after all the rendering operations + * (for example at the end of the {@link AppState#postRender() postRender()} method of the attached app state.) + */ + public void postRender(); + + /** + * Handles moving filters from the main view to each eye. + */ + public void moveScreenProcessingToEyes(); +} diff --git a/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java new file mode 100644 index 000000000..9b78396e5 --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOSVR.java @@ -0,0 +1,957 @@ +package com.jme3.util; + +import java.awt.GraphicsEnvironment; +import java.util.Iterator; +import java.util.logging.Logger; + +import com.jme3.app.VREnvironment; +import com.jme3.input.vr.OSVR; +import com.jme3.input.vr.VRAPI; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.post.CartoonSSAO; +import com.jme3.post.Filter; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.FilterUtil; +import com.jme3.post.SceneProcessor; +import com.jme3.post.filters.FogFilter; +import com.jme3.post.filters.TranslucentBucketFilter; +import com.jme3.post.ssao.SSAOFilter; +import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue.Bucket; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.VertexBuffer; +import com.jme3.shadow.DirectionalLightShadowFilter; +import com.jme3.shadow.VRDirectionalLightShadowRenderer; +import com.jme3.system.jopenvr.DistortionCoordinates_t; +import com.jme3.system.jopenvr.JOpenVRLibrary; +import com.jme3.system.jopenvr.OpenVRUtil; +import com.jme3.system.jopenvr.Texture_t; +import com.jme3.system.jopenvr.VR_IVRSystem_FnTable; +import com.jme3.system.lwjgl.LwjglWindow; +import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_RenderBufferOpenGL; +import com.jme3.system.osvr.osvrrendermanageropengl.OSVR_ViewportDescription; +import com.jme3.system.osvr.osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import com.jme3.ui.Picture; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.PointerByReference; + +public class VRViewManagerOSVR extends AbstractVRViewManager{ + private static final Logger logger = Logger.getLogger(VRViewManagerOpenVR.class.getName()); + + private Camera leftCamera; + private ViewPort leftViewport; + private FilterPostProcessor leftPostProcessor; + private Texture2D leftEyeTexture; + private Texture2D leftEyeDepth; + + private Camera rightCamera; + private ViewPort rightViewport; + private FilterPostProcessor rightPostProcessor; + private Texture2D rightEyeTexture; + private Texture2D rightEyeDepth; + + // OpenVR values + private Texture_t leftTextureType; + private Texture_t rightTextureType; + + // OSVR values + OSVR_RenderBufferOpenGL.ByValue[] osvr_renderBuffer; + OSVR_ViewportDescription.ByValue osvr_viewDescFull; + OSVR_ViewportDescription.ByValue osvr_viewDescLeft; + OSVR_ViewportDescription.ByValue osvr_viewDescRight; + Pointer osvr_rmBufferState; + + //private static boolean useCustomDistortion; + private float heightAdjustment; + + private Texture2D dualEyeTex; + + private final PointerByReference grabRBS = new PointerByReference(); + + private float resMult = 1f; + + //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(); + + /** + * Create a new VR view manager attached to the given {@link VREnvironment VR environment}. + * @param environment the {@link VREnvironment VR environment} to which this view manager is attached. + */ + public VRViewManagerOSVR(VREnvironment environment){ + this.environment = environment; + } + + /** + * Get the {@link Camera camera} attached to the left eye. + * @return the {@link Camera camera} attached to the left eye. + * @see #getRightCamera() + */ + public Camera getLeftCamera() { + return leftCamera; + } + + /** + * Get the {@link Camera camera} attached to the right eye. + * @return the {@link Camera camera} attached to the right eye. + * @see #getLeftCamera() + */ + public Camera getRightCamera() { + return rightCamera; + } + + /** + * Get the {@link ViewPort viewport} attached to the left eye. + * @return the {@link ViewPort viewport} attached to the left eye. + * @see #getRightViewport() + */ + public ViewPort getLeftViewport() { + return leftViewport; + } + + /** + * Get the {@link ViewPort viewport} attached to the right eye. + * @return the {@link ViewPort viewport} attached to the right eye. + * @see #getLeftViewport() + */ + public ViewPort getRightViewport() { + return rightViewport; + } + + /** + * Get the identifier of the left eye texture. + * @return the identifier of the left eye texture. + * @see #getRightTexId() + * @see #getFullTexId() + */ + protected int getLeftTexId() { + return (int)leftEyeTexture.getImage().getId(); + } + + /** + * Get the identifier of the right eye texture. + * @return the identifier of the right eye texture. + * @see #getLeftTexId() + * @see #getFullTexId() + */ + protected int getRightTexId() { + return (int)rightEyeTexture.getImage().getId(); + } + + /** + * Get the identifier of the full (dual eye) texture. + * @return the identifier of the full (dual eye) texture. + * @see #getLeftTexId() + * @see #getRightTexId() + */ + private int getFullTexId() { + return (int)dualEyeTex.getImage().getId(); + } + + /** + * Get the height adjustment to apply to the cameras before rendering. + * @return the height adjustment to apply to the cameras before rendering. + * @see #setHeightAdjustment(float) + */ + public float getHeightAdjustment() { + return heightAdjustment; + } + + /** + * Set the height adjustment to apply to the cameras before rendering. + * @param amount the height adjustment to apply to the cameras before rendering. + * @see #getHeightAdjustment() + */ + public void setHeightAdjustment(float amount) { + heightAdjustment = amount; + } + + /** + * Get the resolution multiplier. + * @return the resolution multiplier. + * @see #setResolutionMultiplier(float) + */ + public float getResolutionMuliplier() { + return resMult; + } + + /** + * Set the resolution multiplier. + * @param resMult the resolution multiplier. + * @see #getResolutionMuliplier() + */ + public void setResolutionMultiplier(float resMult) { + this.resMult = resMult; + } + + /** + * Initialize the system binds of the textures. + */ + private void initTextureSubmitStructs() { + leftTextureType = new Texture_t(); + rightTextureType = new Texture_t(); + + // must be OSVR + osvr_renderBuffer = new OSVR_RenderBufferOpenGL.ByValue[2]; + osvr_renderBuffer[OSVR.EYE_LEFT] = new OSVR_RenderBufferOpenGL.ByValue(); + osvr_renderBuffer[OSVR.EYE_RIGHT] = new OSVR_RenderBufferOpenGL.ByValue(); + osvr_renderBuffer[OSVR.EYE_LEFT].setAutoSynch(false); + osvr_renderBuffer[OSVR.EYE_RIGHT].setAutoSynch(false); + osvr_viewDescFull = new OSVR_ViewportDescription.ByValue(); + osvr_viewDescFull.setAutoSynch(false); + osvr_viewDescFull.left = osvr_viewDescFull.lower = 0.0; + osvr_viewDescFull.width = osvr_viewDescFull.height = 1.0; + osvr_viewDescLeft = new OSVR_ViewportDescription.ByValue(); + osvr_viewDescLeft.setAutoSynch(false); + osvr_viewDescLeft.left = osvr_viewDescLeft.lower = 0.0; + osvr_viewDescLeft.width = 0.5; + osvr_viewDescLeft.height = 1.0; + osvr_viewDescRight = new OSVR_ViewportDescription.ByValue(); + osvr_viewDescRight.setAutoSynch(false); + osvr_viewDescRight.left = 0.5; + osvr_viewDescRight.lower = 0.0; + osvr_viewDescRight.width = 0.5; + osvr_viewDescRight.height = 1.0; + osvr_viewDescRight.write(); + osvr_viewDescLeft.write(); + osvr_viewDescFull.write(); + osvr_renderBuffer[OSVR.EYE_LEFT].depthStencilBufferName = -1; + osvr_renderBuffer[OSVR.EYE_LEFT].colorBufferName = -1; + osvr_renderBuffer[OSVR.EYE_RIGHT].depthStencilBufferName = -1; + osvr_renderBuffer[OSVR.EYE_RIGHT].colorBufferName = -1; + } + + /** + * Register the OSVR OpenGL buffer. + * @param buf the OSVR OpenGL buffer. + */ + private void registerOSVRBuffer(OSVR_RenderBufferOpenGL.ByValue buf) { + + if (environment != null){ + OsvrRenderManagerOpenGLLibrary.osvrRenderManagerStartRegisterRenderBuffers(grabRBS); + OsvrRenderManagerOpenGLLibrary.osvrRenderManagerRegisterRenderBufferOpenGL(grabRBS.getValue(), buf); + OsvrRenderManagerOpenGLLibrary.osvrRenderManagerFinishRegisterRenderBuffers(((OSVR)environment.getVRHardware()).getCompositor(), grabRBS.getValue(), (byte)0); + + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Send the textures to the two eyes. + */ + public void postRender() { + + if (environment != null){ + if( environment.isInVR() ) { + VRAPI api = environment.getVRHardware(); + if( api.getCompositor() != null ) { + // using the compositor... + int errl = 0, errr = 0; + if( environment.isInstanceRendering() ) { + if( leftTextureType.handle == -1 || leftTextureType.handle != getFullTexId() ) { + leftTextureType.handle = getFullTexId(); + if( leftTextureType.handle != -1 ) { + leftTextureType.write(); + if( api instanceof OSVR ) { + osvr_renderBuffer[OSVR.EYE_LEFT].colorBufferName = leftTextureType.handle; + osvr_renderBuffer[OSVR.EYE_LEFT].depthStencilBufferName = dualEyeTex.getImage().getId(); + osvr_renderBuffer[OSVR.EYE_LEFT].write(); + registerOSVRBuffer(osvr_renderBuffer[OSVR.EYE_LEFT]); + } + } + } else { + if( api instanceof OSVR ) { + ((OSVR)api).handleRenderBufferPresent(osvr_viewDescLeft, osvr_viewDescRight, + osvr_renderBuffer[OSVR.EYE_LEFT], osvr_renderBuffer[OSVR.EYE_LEFT]); + } + } + } else if( leftTextureType.handle == -1 || rightTextureType.handle == -1 || + leftTextureType.handle != getLeftTexId() || rightTextureType.handle != getRightTexId() ) { + leftTextureType.handle = getLeftTexId(); + if( leftTextureType.handle != -1 ) { + logger.fine("Writing Left texture to native memory at " + leftTextureType.getPointer()); + leftTextureType.write(); + if( api instanceof OSVR ) { + osvr_renderBuffer[OSVR.EYE_LEFT].colorBufferName = leftTextureType.handle; + if( leftEyeDepth != null ) osvr_renderBuffer[OSVR.EYE_LEFT].depthStencilBufferName = leftEyeDepth.getImage().getId(); + osvr_renderBuffer[OSVR.EYE_LEFT].write(); + registerOSVRBuffer(osvr_renderBuffer[OSVR.EYE_LEFT]); + } + } + rightTextureType.handle = getRightTexId(); + if( rightTextureType.handle != -1 ) { + logger.fine("Writing Right texture to native memory at " + leftTextureType.getPointer()); + rightTextureType.write(); + if( api instanceof OSVR ) { + osvr_renderBuffer[OSVR.EYE_RIGHT].colorBufferName = rightTextureType.handle; + if( rightEyeDepth != null ) osvr_renderBuffer[OSVR.EYE_RIGHT].depthStencilBufferName = rightEyeDepth.getImage().getId(); + osvr_renderBuffer[OSVR.EYE_RIGHT].write(); + registerOSVRBuffer(osvr_renderBuffer[OSVR.EYE_RIGHT]); + } + } + } else { + if( api instanceof OSVR ) { + ((OSVR)api).handleRenderBufferPresent(osvr_viewDescFull, osvr_viewDescFull, + osvr_renderBuffer[OSVR.EYE_LEFT], osvr_renderBuffer[OSVR.EYE_RIGHT]); + } + } + + if( errl != 0 ){ + logger.severe("Submit to left compositor error: " + OpenVRUtil.getEVRCompositorErrorString(errl)+" ("+Integer.toString(errl)+")"); + logger.severe(" Texture color space: "+OpenVRUtil.getEColorSpaceString(leftTextureType.eColorSpace)); + logger.severe(" Texture type: "+OpenVRUtil.getETextureTypeString(leftTextureType.eType)); + logger.severe(" Texture handle: "+leftTextureType.handle); + + logger.severe(" Left eye texture "+leftEyeTexture.getName()+" ("+leftEyeTexture.getImage().getId()+")"); + logger.severe(" Type: "+leftEyeTexture.getType()); + logger.severe(" Size: "+leftEyeTexture.getImage().getWidth()+"x"+leftEyeTexture.getImage().getHeight()); + logger.severe(" Image depth: "+leftEyeTexture.getImage().getDepth()); + logger.severe(" Image format: "+leftEyeTexture.getImage().getFormat()); + logger.severe(" Image color space: "+leftEyeTexture.getImage().getColorSpace()); + + } + + if( errr != 0 ){ + logger.severe("Submit to right compositor error: " + OpenVRUtil.getEVRCompositorErrorString(errl)+" ("+Integer.toString(errl)+")"); + logger.severe(" Texture color space: "+OpenVRUtil.getEColorSpaceString(rightTextureType.eColorSpace)); + logger.severe(" Texture type: "+OpenVRUtil.getETextureTypeString(rightTextureType.eType)); + logger.severe(" Texture handle: "+rightTextureType.handle); + + logger.severe(" Right eye texture "+rightEyeTexture.getName()+" ("+rightEyeTexture.getImage().getId()+")"); + logger.severe(" Type: "+rightEyeTexture.getType()); + logger.severe(" Size: "+rightEyeTexture.getImage().getWidth()+"x"+rightEyeTexture.getImage().getHeight()); + logger.severe(" Image depth: "+rightEyeTexture.getImage().getDepth()); + logger.severe(" Image format: "+rightEyeTexture.getImage().getFormat()); + logger.severe(" Image color space: "+rightEyeTexture.getImage().getColorSpace()); + } + } + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + + /** + * Initialize the VR view manager. + */ + public void initialize() { + + logger.config("Initializing VR view manager."); + + if (environment != null){ + initTextureSubmitStructs(); + setupCamerasAndViews(); + setupVRScene(); + moveScreenProcessingToEyes(); + if( environment.hasTraditionalGUIOverlay() ) { + + environment.getVRMouseManager().initialize(); + + // update the pose to position the gui correctly on start + update(0f); + environment.getVRGUIManager().positionGui(); + } + + if (environment.getApplication() != null){ + // if we are OSVR, our primary mirror window needs to be the same size as the render manager's output... + if( environment.getVRHardware() instanceof OSVR ) { + int origWidth = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getWidth(); + int origHeight = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getHeight(); + long window = ((LwjglWindow)environment.getApplication().getContext()).getWindowHandle(); + Vector2f windowSize = new Vector2f(); + ((OSVR)environment.getVRHardware()).getRenderSize(windowSize); + windowSize.x = Math.max(windowSize.x * 2f, leftCamera.getWidth()); + org.lwjgl.glfw.GLFW.glfwSetWindowSize(window, (int)windowSize.x, (int)windowSize.y); + environment.getApplication().getContext().getSettings().setResolution((int)windowSize.x, (int)windowSize.y); + + if (environment.getApplication().getRenderManager() != null) { + environment.getApplication().getRenderManager().notifyReshape((int)windowSize.x, (int)windowSize.y); + } + + org.lwjgl.glfw.GLFW.glfwSetWindowPos(window, origWidth - (int)windowSize.x, 32); + + org.lwjgl.glfw.GLFW.glfwFocusWindow(window); + + org.lwjgl.glfw.GLFW.glfwSetCursorPos(window, origWidth / 2.0, origHeight / 2.0); + + logger.config("Initialized VR view manager [SUCCESS]"); + } else { + throw new IllegalStateException("Underlying VR hardware should be "+OSVR.class.getSimpleName()); + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + + + } + + /** + * Prepare the size of the given {@link Camera camera} to adapt it to the underlying rendering context. + * @param cam the {@link Camera camera} to prepare. + * @param xMult the camera width multiplier. + */ + private void prepareCameraSize(Camera cam, float xMult) { + + if (environment != null){ + + if (environment.getApplication() != null){ + + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + + Vector2f size = new Vector2f(); + VRAPI vrhmd = environment.getVRHardware(); + + if( vrhmd == null ) { + size.x = 1280f; + size.y = 720f; + } else { + vrhmd.getRenderSize(size); + } + + if( size.x < environment.getApplication().getContext().getSettings().getWidth() ) { + size.x = environment.getApplication().getContext().getSettings().getWidth(); + } + if( size.y < environment.getApplication().getContext().getSettings().getHeight() ) { + size.y = environment.getApplication().getContext().getSettings().getHeight(); + } + + if( environment.isInstanceRendering() ){ + size.x *= 2f; + } + + // other adjustments + size.x *= xMult; + size.x *= resMult; + size.y *= resMult; + + if( cam.getWidth() != size.x || cam.getHeight() != size.y ){ + cam.resize((int)size.x, (int)size.y, false); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Replaces rootNode as the main cameras scene with the distortion mesh + */ + private void setupVRScene(){ + + if (environment != null){ + if (environment.getApplication() != null){ + // no special scene to setup if we are doing instancing + if( environment.isInstanceRendering() ) { + // distortion has to be done with compositor here... we want only one pass on our end! + if( environment.getApplication().getContext().getSettings().isSwapBuffers() ) { + setupMirrorBuffers(environment.getCamera(), dualEyeTex, true); + } + return; + } + + leftEyeTexture = (Texture2D) leftViewport.getOutputFrameBuffer().getColorBuffer().getTexture(); + rightEyeTexture = (Texture2D)rightViewport.getOutputFrameBuffer().getColorBuffer().getTexture(); + leftEyeDepth = (Texture2D) leftViewport.getOutputFrameBuffer().getDepthBuffer().getTexture(); + rightEyeDepth = (Texture2D)rightViewport.getOutputFrameBuffer().getDepthBuffer().getTexture(); + + // main viewport is either going to be a distortion scene or nothing + // mirroring is handled by copying framebuffers + Iterator spatialIter = environment.getApplication().getViewPort().getScenes().iterator(); + while(spatialIter.hasNext()){ + environment.getApplication().getViewPort().detachScene(spatialIter.next()); + } + + spatialIter = environment.getApplication().getGuiViewPort().getScenes().iterator(); + while(spatialIter.hasNext()){ + environment.getApplication().getGuiViewPort().detachScene(spatialIter.next()); + } + + // only setup distortion scene if compositor isn't running (or using custom mesh distortion option) + if( environment.getVRHardware().getCompositor() == null ) { + Node distortionScene = new Node(); + Material leftMat = new Material(environment.getApplication().getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md"); + leftMat.setTexture("Texture", leftEyeTexture); + Geometry leftEye = new Geometry("box", setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Left, environment.getVRHardware())); + leftEye.setMaterial(leftMat); + distortionScene.attachChild(leftEye); + + Material rightMat = new Material(environment.getApplication().getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md"); + rightMat.setTexture("Texture", rightEyeTexture); + Geometry rightEye = new Geometry("box", setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Right, environment.getVRHardware())); + rightEye.setMaterial(rightMat); + distortionScene.attachChild(rightEye); + + distortionScene.updateGeometricState(); + + environment.getApplication().getViewPort().attachScene(distortionScene); + + //if( useCustomDistortion ) setupFinalFullTexture(app.getViewPort().getCamera()); + } + + if( environment.getApplication().getContext().getSettings().isSwapBuffers() ) { + setupMirrorBuffers(environment.getCamera(), leftEyeTexture, false); + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + + + } + + /** + * Update the VR view manager. + * This method is called by the attached {@link VRApplication VR application} and should not be called manually. + * @param tpf the time per frame. + */ + public void update(float tpf) { + + 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.updatePose(); + 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 += heightAdjustment; + cam.setFrame(finalPosition, finalRotation); + } + + /** + * Handles moving filters from the main view to each eye + */ + public void moveScreenProcessingToEyes() { + if( rightViewport == null ){ + return; + } + + if (environment != null){ + if (environment.getApplication() != null){ + + syncScreenProcessing(environment.getApplication().getViewPort()); + environment.getApplication().getViewPort().clearProcessors(); + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Sets the two views to use the list of {@link SceneProcessor processors}. + * @param sourceViewport the {@link ViewPort viewport} that contains the processors to use. + */ + public void syncScreenProcessing(ViewPort sourceViewport) { + if( rightViewport == null ){ + return; + } + + if (environment != null){ + if (environment.getApplication() != null){ + // setup post processing filters + if( rightPostProcessor == null ) { + rightPostProcessor = new FilterPostProcessor(environment.getApplication().getAssetManager()); + leftPostProcessor = new FilterPostProcessor(environment.getApplication().getAssetManager()); + } + // clear out all filters & processors, to start from scratch + rightPostProcessor.removeAllFilters(); + leftPostProcessor.removeAllFilters(); + leftViewport.clearProcessors(); + rightViewport.clearProcessors(); + // if we have no processors to sync, don't add the FilterPostProcessor + if( sourceViewport.getProcessors().isEmpty() ) return; + // add post processors we just made, which are empty + leftViewport.addProcessor(leftPostProcessor); + rightViewport.addProcessor(rightPostProcessor); + // go through all of the filters in the processors list + // add them to the left viewport processor & clone them to the right + for(SceneProcessor sceneProcessor : sourceViewport.getProcessors()) { + if (sceneProcessor instanceof FilterPostProcessor) { + for(Filter f : ((FilterPostProcessor)sceneProcessor).getFilterList() ) { + if( f instanceof TranslucentBucketFilter ) { + // just remove this filter, we will add it at the end manually + ((FilterPostProcessor)sceneProcessor).removeFilter(f); + } else { + leftPostProcessor.addFilter(f); + // clone to the right + Filter f2; + if(f instanceof FogFilter){ + f2 = FilterUtil.cloneFogFilter((FogFilter)f); + } else if (f instanceof CartoonSSAO ) { + f2 = new CartoonSSAO((CartoonSSAO)f); + } else if (f instanceof SSAOFilter){ + f2 = FilterUtil.cloneSSAOFilter((SSAOFilter)f); + } else if (f instanceof DirectionalLightShadowFilter){ + f2 = FilterUtil.cloneDirectionalLightShadowFilter(environment.getApplication().getAssetManager(), (DirectionalLightShadowFilter)f); + } else { + f2 = f; // dof, bloom, lightscattering etc. + } + rightPostProcessor.addFilter(f2); + } + } + } else if (sceneProcessor instanceof VRDirectionalLightShadowRenderer) { + // shadow processing + // TODO: make right shadow processor use same left shadow maps for performance + VRDirectionalLightShadowRenderer dlsr = (VRDirectionalLightShadowRenderer) sceneProcessor; + VRDirectionalLightShadowRenderer dlsrRight = dlsr.clone(); + dlsrRight.setLight(dlsr.getLight()); + rightViewport.getProcessors().add(0, dlsrRight); + leftViewport.getProcessors().add(0, sceneProcessor); + } + } + // make sure each has a translucent filter renderer + leftPostProcessor.addFilter(new TranslucentBucketFilter()); + rightPostProcessor.addFilter(new TranslucentBucketFilter()); + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + private void setupCamerasAndViews() { + + if (environment != null){ + if (environment.getApplication() != null){ + // get desired frustrum from original camera + Camera origCam = environment.getCamera(); + float fFar = origCam.getFrustumFar(); + float fNear = origCam.getFrustumNear(); + + // if we are using OSVR get the eye info here + if( environment.getVRHardware() instanceof OSVR ) { + ((OSVR)environment.getVRHardware()).getEyeInfo(); + } + + // restore frustrum on distortion scene cam, if needed + if( environment.isInstanceRendering() ) { + leftCamera = origCam; + } else if( environment.compositorAllowed() == false ) { + origCam.setFrustumFar(100f); + origCam.setFrustumNear(1f); + leftCamera = origCam.clone(); + prepareCameraSize(origCam, 2f); + } else { + leftCamera = origCam.clone(); + } + + leftCamera.setFrustumPerspective(environment.getDefaultFOV(), environment.getDefaultAspect(), fNear, fFar); + + prepareCameraSize(leftCamera, 1f); + if( environment.getVRHardware() != null ) leftCamera.setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionLeftEye(leftCamera)); + //org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_SRGB); + + if( !environment.isInstanceRendering()) { + leftViewport = setupViewBuffers(leftCamera, LEFT_VIEW_NAME); + rightCamera = leftCamera.clone(); + if( environment.getVRHardware() != null ){ + rightCamera.setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionRightEye(rightCamera)); + } + rightViewport = setupViewBuffers(rightCamera, RIGHT_VIEW_NAME); + } else { + + System.err.println("[VRViewManager] THIS CODE NEED CHANGES !!!"); + leftViewport = environment.getApplication().getViewPort(); + //leftViewport.attachScene(app.getRootNode()); + rightCamera = leftCamera.clone(); + if( environment.getVRHardware() != null ){ + rightCamera.setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionRightEye(rightCamera)); + } + + org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_CLIP_DISTANCE0); + + //FIXME: [jme-vr] Fix with JMonkey next release + //RenderManager._VRInstancing_RightCamProjection = camRight.getViewProjectionMatrix(); + setupFinalFullTexture(environment.getApplication().getViewPort().getCamera()); + } + + // setup gui + environment.getVRGUIManager().setupGui(leftCamera, rightCamera, leftViewport, rightViewport); + + if( environment.getVRHardware() != null ) { + // call these to cache the results internally + environment.getVRHardware().getHMDMatrixPoseLeftEye(); + environment.getVRHardware().getHMDMatrixPoseRightEye(); + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + private ViewPort setupMirrorBuffers(Camera cam, Texture tex, boolean expand) { + + if (environment != null){ + if (environment.getApplication() != null){ + Camera clonecam = cam.clone(); + ViewPort viewPort = environment.getApplication().getRenderManager().createPostView("MirrorView", clonecam); + clonecam.setParallelProjection(true); + viewPort.setClearFlags(true, true, true); + viewPort.setBackgroundColor(ColorRGBA.Black); + Picture pic = new Picture("fullscene"); + pic.setLocalTranslation(-0.75f, -0.5f, 0f); + if( expand ) { + pic.setLocalScale(3f, 1f, 1f); + } else { + pic.setLocalScale(1.5f, 1f, 1f); + } + pic.setQueueBucket(Bucket.Opaque); + pic.setTexture(environment.getApplication().getAssetManager(), (Texture2D)tex, false); + viewPort.attachScene(pic); + viewPort.setOutputFrameBuffer(null); + + pic.updateGeometricState(); + + return viewPort; + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + private void setupFinalFullTexture(Camera cam) { + + if (environment != null){ + if (environment.getApplication() != null){ + // create offscreen framebuffer + FrameBuffer out = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); + //offBuffer.setSrgb(true); + + //setup framebuffer's texture + dualEyeTex = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); + dualEyeTex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); + dualEyeTex.setMagFilter(Texture.MagFilter.Bilinear); + + logger.config("Dual eye texture "+dualEyeTex.getName()+" ("+dualEyeTex.getImage().getId()+")"); + logger.config(" Type: "+dualEyeTex.getType()); + logger.config(" Size: "+dualEyeTex.getImage().getWidth()+"x"+dualEyeTex.getImage().getHeight()); + logger.config(" Image depth: "+dualEyeTex.getImage().getDepth()); + logger.config(" Image format: "+dualEyeTex.getImage().getFormat()); + logger.config(" Image color space: "+dualEyeTex.getImage().getColorSpace()); + + //setup framebuffer to use texture + out.setDepthBuffer(Image.Format.Depth); + out.setColorTexture(dualEyeTex); + + ViewPort viewPort = environment.getApplication().getViewPort(); + viewPort.setClearFlags(true, true, true); + viewPort.setBackgroundColor(ColorRGBA.Black); + viewPort.setOutputFrameBuffer(out); + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + private ViewPort setupViewBuffers(Camera cam, String viewName){ + + if (environment != null){ + if (environment.getApplication() != null){ + // create offscreen framebuffer + FrameBuffer offBufferLeft = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); + //offBufferLeft.setSrgb(true); + + //setup framebuffer's texture + Texture2D offTex = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); + offTex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); + offTex.setMagFilter(Texture.MagFilter.Bilinear); + + //setup framebuffer to use texture + offBufferLeft.setDepthBuffer(Image.Format.Depth); + offBufferLeft.setColorTexture(offTex); + + ViewPort viewPort = environment.getApplication().getRenderManager().createPreView(viewName, cam); + viewPort.setClearFlags(true, true, true); + viewPort.setBackgroundColor(ColorRGBA.Black); + + Iterator spatialIter = environment.getApplication().getViewPort().getScenes().iterator(); + while(spatialIter.hasNext()){ + viewPort.attachScene(spatialIter.next()); + } + + //set viewport to render to offscreen framebuffer + viewPort.setOutputFrameBuffer(offBufferLeft); + return viewPort; + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Setup a distortion mesh for the stereo view. + * @param eye the eye to apply. + * @param api the underlying VR api + * @return the distorted mesh. + */ + public static Mesh setupDistortionMesh(int eye, VRAPI api) { + Mesh distortionMesh = new Mesh(); + float m_iLensGridSegmentCountH = 43, m_iLensGridSegmentCountV = 43; + + float w = 1f / (m_iLensGridSegmentCountH - 1f); + float h = 1f / (m_iLensGridSegmentCountV - 1f); + + float u, v; + + float verts[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 3]; + + float texcoordR[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; + float texcoordG[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; + float texcoordB[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; + + int vertPos = 0, coordPos = 0; + + float Xoffset = eye == JOpenVRLibrary.EVREye.EVREye_Eye_Left ? -1f : 0; + for (int y = 0; y < m_iLensGridSegmentCountV; y++) { + for (int x = 0; x < m_iLensGridSegmentCountH; x++) { + u = x * w; + v = 1 - y * h; + verts[vertPos] = Xoffset + u; // x + verts[vertPos + 1] = -1 + 2 * y * h; // y + verts[vertPos + 2] = 0f; // z + vertPos += 3; + + DistortionCoordinates_t dc0 = new DistortionCoordinates_t(); + if( api.getVRSystem() == null ) { + // default to no distortion + texcoordR[coordPos] = u; + texcoordR[coordPos + 1] = 1 - v; + texcoordG[coordPos] = u; + texcoordG[coordPos + 1] = 1 - v; + texcoordB[coordPos] = u; + texcoordB[coordPos + 1] = 1 - v; + } else { + ((VR_IVRSystem_FnTable)api.getVRSystem()).ComputeDistortion.apply(eye, u, v, dc0); + + texcoordR[coordPos] = dc0.rfRed[0]; + texcoordR[coordPos + 1] = 1 - dc0.rfRed[1]; + texcoordG[coordPos] = dc0.rfGreen[0]; + texcoordG[coordPos + 1] = 1 - dc0.rfGreen[1]; + texcoordB[coordPos] = dc0.rfBlue[0]; + texcoordB[coordPos + 1] = 1 - dc0.rfBlue[1]; + } + + coordPos += 2; + } + } + + // have UV coordinates & positions, now to setup indices + + int[] indices = new int[(int) ((m_iLensGridSegmentCountV - 1) * (m_iLensGridSegmentCountH - 1)) * 6]; + int indexPos = 0; + int a, b, c, d; + + int offset = 0; + for (int y = 0; y < m_iLensGridSegmentCountV - 1; y++) { + for (int x = 0; x < m_iLensGridSegmentCountH - 1; x++) { + a = (int) (m_iLensGridSegmentCountH * y + x + offset); + b = (int) (m_iLensGridSegmentCountH * y + x + 1 + offset); + c = (int) ((y + 1) * m_iLensGridSegmentCountH + x + 1 + offset); + d = (int) ((y + 1) * m_iLensGridSegmentCountH + x + offset); + + indices[indexPos] = a; + indices[indexPos + 1] = b; + indices[indexPos + 2] = c; + + indices[indexPos + 3] = a; + indices[indexPos + 4] = c; + indices[indexPos + 5] = d; + + indexPos += 6; + } + } + + // OK, create the mesh + distortionMesh.setBuffer(VertexBuffer.Type.Position, 3, verts); + distortionMesh.setBuffer(VertexBuffer.Type.Index, 1, indices); + distortionMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, texcoordR); + distortionMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, texcoordG); + distortionMesh.setBuffer(VertexBuffer.Type.TexCoord3, 2, texcoordB); + distortionMesh.setStatic(); + return distortionMesh; + } +} diff --git a/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java new file mode 100644 index 000000000..49d08578b --- /dev/null +++ b/jme3-vr/src/main/java/com/jme3/util/VRViewManagerOpenVR.java @@ -0,0 +1,732 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.util; + +import com.jme3.app.VREnvironment; +import com.jme3.input.vr.OpenVR; +import com.jme3.input.vr.VRAPI; +import com.jme3.material.Material; +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.renderer.queue.RenderQueue.Bucket; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.VertexBuffer; +import com.jme3.system.jopenvr.DistortionCoordinates_t; +import com.jme3.system.jopenvr.JOpenVRLibrary; +import com.jme3.system.jopenvr.OpenVRUtil; +import com.jme3.system.jopenvr.Texture_t; +import com.jme3.system.jopenvr.VRTextureBounds_t; +import com.jme3.system.jopenvr.VR_IVRSystem_FnTable; +import com.jme3.texture.FrameBuffer; +import com.jme3.texture.Image; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture2D; +import com.jme3.ui.Picture; + +import java.util.Iterator; +import java.util.logging.Logger; + +/** + * A VR view manager based on OpenVR. This class enable to submit 3D views to the VR compositor. + * @author reden - phr00t - https://github.com/phr00t + * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org + */ +public class VRViewManagerOpenVR extends AbstractVRViewManager { + + private static final Logger logger = Logger.getLogger(VRViewManagerOpenVR.class.getName()); + + // OpenVR values + private VRTextureBounds_t leftTextureBounds; + private Texture_t leftTextureType; + + private VRTextureBounds_t rightTextureBounds; + private Texture_t rightTextureType; + + private Texture2D dualEyeTex; + + //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(); + + /** + * Create a new VR view manager attached to the given {@link VREnvironment VR environment}. + * @param environment the {@link VREnvironment VR environment} to which this view manager is attached. + */ + public VRViewManagerOpenVR(VREnvironment environment){ + this.environment = environment; + } + + /** + * Get the identifier of the left eye texture. + * @return the identifier of the left eye texture. + * @see #getRightTexId() + * @see #getFullTexId() + */ + protected int getLeftTexId() { + return (int)getLeftTexture().getImage().getId(); + } + + /** + * Get the identifier of the right eye texture. + * @return the identifier of the right eye texture. + * @see #getLeftTexId() + * @see #getFullTexId() + */ + protected int getRightTexId() { + return (int)getRightTexture().getImage().getId(); + } + + /** + * Get the identifier of the full (dual eye) texture. + * @return the identifier of the full (dual eye) texture. + * @see #getLeftTexId() + * @see #getRightTexId() + */ + private int getFullTexId() { + return (int)dualEyeTex.getImage().getId(); + } + + /** + * Initialize the system binds of the textures. + */ + private void initTextureSubmitStructs() { + leftTextureType = new Texture_t(); + rightTextureType = new Texture_t(); + + if (environment != null){ + if( environment.getVRHardware() instanceof OpenVR ) { + leftTextureBounds = new VRTextureBounds_t(); + rightTextureBounds = new VRTextureBounds_t(); + // left eye + leftTextureBounds.uMax = 0.5f; + leftTextureBounds.uMin = 0f; + leftTextureBounds.vMax = 1f; + leftTextureBounds.vMin = 0f; + leftTextureBounds.setAutoSynch(false); + leftTextureBounds.setAutoRead(false); + leftTextureBounds.setAutoWrite(false); + leftTextureBounds.write(); + // right eye + rightTextureBounds.uMax = 1f; + rightTextureBounds.uMin = 0.5f; + rightTextureBounds.vMax = 1f; + rightTextureBounds.vMin = 0f; + rightTextureBounds.setAutoSynch(false); + rightTextureBounds.setAutoRead(false); + rightTextureBounds.setAutoWrite(false); + rightTextureBounds.write(); + // texture type + leftTextureType.eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Gamma; + leftTextureType.eType = JOpenVRLibrary.ETextureType.ETextureType_TextureType_OpenGL; + leftTextureType.setAutoSynch(false); + leftTextureType.setAutoRead(false); + leftTextureType.setAutoWrite(false); + leftTextureType.handle = -1; + rightTextureType.eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Gamma; + rightTextureType.eType = JOpenVRLibrary.ETextureType.ETextureType_TextureType_OpenGL; + rightTextureType.setAutoSynch(false); + rightTextureType.setAutoRead(false); + rightTextureType.setAutoWrite(false); + rightTextureType.handle = -1; + + + logger.config("Init eyes native texture binds"); + logger.config(" Left eye texture"); + logger.config(" address: "+leftTextureType.getPointer()); + logger.config(" size: "+leftTextureType.size()+" bytes"); + logger.config(" color space: "+OpenVRUtil.getEColorSpaceString(leftTextureType.eColorSpace)); + logger.config(" type: "+OpenVRUtil.getETextureTypeString(leftTextureType.eType)); + logger.config(" auto read: "+leftTextureType.getAutoRead()); + logger.config(" auto write: "+leftTextureType.getAutoWrite()); + logger.config(" handle address: "+leftTextureType.handle); + logger.config(" handle value: "+leftTextureType.handle); + logger.config(""); + logger.config(" Right eye texture"); + logger.config(" address: "+rightTextureType.getPointer()); + logger.config(" size: "+rightTextureType.size()+" bytes"); + logger.config(" color space: "+OpenVRUtil.getEColorSpaceString(rightTextureType.eColorSpace)); + logger.config(" type: "+OpenVRUtil.getETextureTypeString(rightTextureType.eType)); + logger.config(" auto read: "+rightTextureType.getAutoRead()); + logger.config(" auto write: "+rightTextureType.getAutoWrite()); + logger.config(" handle address: "+rightTextureType.handle); + logger.config(" handle value: "+rightTextureType.handle); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + @Override + public void postRender() { + + if (environment != null){ + if( environment.isInVR() ) { + VRAPI api = environment.getVRHardware(); + if( api.getCompositor() != null ) { + // using the compositor... + int errl = 0, errr = 0; + if( environment.isInstanceRendering() ) { + if( leftTextureType.handle == -1 || leftTextureType.handle != getFullTexId() ) { + leftTextureType.handle = getFullTexId(); + if( leftTextureType.handle != -1 ) { + leftTextureType.write(); + } + } else { + if( api instanceof OpenVR ) { + int submitFlag = JOpenVRLibrary.EVRSubmitFlags.EVRSubmitFlags_Submit_Default; + errr = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, leftTextureType, rightTextureBounds, submitFlag); + errl = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, leftTextureType, leftTextureBounds, submitFlag); + } + } + } else if( leftTextureType.handle == -1 || rightTextureType.handle == -1 || + leftTextureType.handle != getLeftTexId() || rightTextureType.handle != getRightTexId() ) { + leftTextureType.handle = getLeftTexId(); + if( leftTextureType.handle != -1 ) { + logger.fine("Writing Left texture to native memory at " + leftTextureType.getPointer()); + leftTextureType.write(); + } + rightTextureType.handle = getRightTexId(); + if( rightTextureType.handle != -1 ) { + logger.fine("Writing Right texture to native memory at " + leftTextureType.getPointer()); + rightTextureType.write(); + } + } else { + if( api instanceof OpenVR ) { + errl = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, leftTextureType, null, + JOpenVRLibrary.EVRSubmitFlags.EVRSubmitFlags_Submit_Default); + errr = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, rightTextureType, null, + JOpenVRLibrary.EVRSubmitFlags.EVRSubmitFlags_Submit_Default); + } else { + + } + } + + if( errl != 0 ){ + logger.severe("Submit to left compositor error: " + OpenVRUtil.getEVRCompositorErrorString(errl)+" ("+Integer.toString(errl)+")"); + logger.severe(" Texture color space: "+OpenVRUtil.getEColorSpaceString(leftTextureType.eColorSpace)); + logger.severe(" Texture type: "+OpenVRUtil.getETextureTypeString(leftTextureType.eType)); + logger.severe(" Texture handle: "+leftTextureType.handle); + + logger.severe(" Left eye texture "+leftEyeTexture.getName()+" ("+leftEyeTexture.getImage().getId()+")"); + logger.severe(" Type: "+leftEyeTexture.getType()); + logger.severe(" Size: "+leftEyeTexture.getImage().getWidth()+"x"+leftEyeTexture.getImage().getHeight()); + logger.severe(" Image depth: "+leftEyeTexture.getImage().getDepth()); + logger.severe(" Image format: "+leftEyeTexture.getImage().getFormat()); + logger.severe(" Image color space: "+leftEyeTexture.getImage().getColorSpace()); + + } + + if( errr != 0 ){ + logger.severe("Submit to right compositor error: " + OpenVRUtil.getEVRCompositorErrorString(errl)+" ("+Integer.toString(errl)+")"); + logger.severe(" Texture color space: "+OpenVRUtil.getEColorSpaceString(rightTextureType.eColorSpace)); + logger.severe(" Texture type: "+OpenVRUtil.getETextureTypeString(rightTextureType.eType)); + logger.severe(" Texture handle: "+rightTextureType.handle); + + logger.severe(" Right eye texture "+rightEyeTexture.getName()+" ("+rightEyeTexture.getImage().getId()+")"); + logger.severe(" Type: "+rightEyeTexture.getType()); + logger.severe(" Size: "+rightEyeTexture.getImage().getWidth()+"x"+rightEyeTexture.getImage().getHeight()); + logger.severe(" Image depth: "+rightEyeTexture.getImage().getDepth()); + logger.severe(" Image format: "+rightEyeTexture.getImage().getFormat()); + logger.severe(" Image color space: "+rightEyeTexture.getImage().getColorSpace()); + } + } + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + + + + } + + + @Override + public void initialize() { + + logger.config("Initializing VR view manager."); + + if (environment != null){ + + initTextureSubmitStructs(); + setupCamerasAndViews(); + setupVRScene(); + moveScreenProcessingToEyes(); + + if( environment.hasTraditionalGUIOverlay() ) { + + environment.getVRMouseManager().initialize(); + + // update the pose to position the gui correctly on start + update(0f); + environment.getVRGUIManager().positionGui(); + } + + logger.config("Initialized VR view manager [SUCCESS]"); + + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Prepare the size of the given {@link Camera camera} to adapt it to the underlying rendering context. + * @param cam the {@link Camera camera} to prepare. + * @param xMult the camera width multiplier. + */ + private void prepareCameraSize(Camera cam, float xMult) { + + if (environment != null){ + + if (environment.getApplication() != null){ + Vector2f size = new Vector2f(); + VRAPI vrhmd = environment.getVRHardware(); + + if( vrhmd == null ) { + size.x = 1280f; + size.y = 720f; + } else { + vrhmd.getRenderSize(size); + } + + if( size.x < environment.getApplication().getContext().getSettings().getWidth() ) { + size.x = environment.getApplication().getContext().getSettings().getWidth(); + } + if( size.y < environment.getApplication().getContext().getSettings().getHeight() ) { + size.y = environment.getApplication().getContext().getSettings().getHeight(); + } + + if( environment.isInstanceRendering() ){ + size.x *= 2f; + } + + // other adjustments + size.x *= xMult; + size.x *= getResolutionMuliplier(); + size.y *= getResolutionMuliplier(); + + if( cam.getWidth() != size.x || cam.getHeight() != size.y ){ + cam.resize((int)size.x, (int)size.y, false); + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + + + } + + /** + * Replaces rootNode as the main cameras scene with the distortion mesh + */ + private void setupVRScene(){ + + + if (environment != null){ + if (environment.getApplication() != null){ + // no special scene to setup if we are doing instancing + if( environment.isInstanceRendering() ) { + // distortion has to be done with compositor here... we want only one pass on our end! + if( environment.getApplication().getContext().getSettings().isSwapBuffers() ) { + setupMirrorBuffers(environment.getCamera(), dualEyeTex, true); + } + return; + } + + leftEyeTexture = (Texture2D) getLeftViewport().getOutputFrameBuffer().getColorBuffer().getTexture(); + rightEyeTexture = (Texture2D)getRightViewport().getOutputFrameBuffer().getColorBuffer().getTexture(); + leftEyeDepth = (Texture2D) getLeftViewport().getOutputFrameBuffer().getDepthBuffer().getTexture(); + rightEyeDepth = (Texture2D)getRightViewport().getOutputFrameBuffer().getDepthBuffer().getTexture(); + + // main viewport is either going to be a distortion scene or nothing + // mirroring is handled by copying framebuffers + Iterator spatialIter = environment.getApplication().getViewPort().getScenes().iterator(); + while(spatialIter.hasNext()){ + environment.getApplication().getViewPort().detachScene(spatialIter.next()); + } + + spatialIter = environment.getApplication().getGuiViewPort().getScenes().iterator(); + while(spatialIter.hasNext()){ + environment.getApplication().getGuiViewPort().detachScene(spatialIter.next()); + } + + // only setup distortion scene if compositor isn't running (or using custom mesh distortion option) + if( environment.getVRHardware().getCompositor() == null ) { + Node distortionScene = new Node(); + Material leftMat = new Material(environment.getApplication().getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md"); + leftMat.setTexture("Texture", leftEyeTexture); + Geometry leftEye = new Geometry("box", setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Left, environment.getVRHardware())); + leftEye.setMaterial(leftMat); + distortionScene.attachChild(leftEye); + + Material rightMat = new Material(environment.getApplication().getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md"); + rightMat.setTexture("Texture", rightEyeTexture); + Geometry rightEye = new Geometry("box", setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Right, environment.getVRHardware())); + rightEye.setMaterial(rightMat); + distortionScene.attachChild(rightEye); + + distortionScene.updateGeometricState(); + + environment.getApplication().getViewPort().attachScene(distortionScene); + + //if( useCustomDistortion ) setupFinalFullTexture(app.getViewPort().getCamera()); + } + + if( environment.getApplication().getContext().getSettings().isSwapBuffers() ) { + setupMirrorBuffers(environment.getCamera(), leftEyeTexture, false); + } + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + @Override + public void update(float tpf) { + + 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.updatePose(); + 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, getLeftCamera()); + finalizeCamera(dev.getHMDVectorPoseRightEye(), objPos, getRightCamera()); + } else { + getLeftCamera().setFrame(objPos, objRot); + getRightCamera().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); + } + + + private void setupCamerasAndViews() { + + if (environment != null){ + // get desired frustrum from original camera + Camera origCam = environment.getCamera(); + float fFar = origCam.getFrustumFar(); + float fNear = origCam.getFrustumNear(); + + // restore frustrum on distortion scene cam, if needed + if( environment.isInstanceRendering() ) { + leftCamera = origCam; + } else if( environment.compositorAllowed() == false ) { + origCam.setFrustumFar(100f); + origCam.setFrustumNear(1f); + leftCamera = origCam.clone(); + prepareCameraSize(origCam, 2f); + } else { + leftCamera = origCam.clone(); + } + + getLeftCamera().setFrustumPerspective(environment.getDefaultFOV(), environment.getDefaultAspect(), fNear, fFar); + + prepareCameraSize(getLeftCamera(), 1f); + if( environment.getVRHardware() != null ) { + getLeftCamera().setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionLeftEye(getLeftCamera())); + } + //org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_SRGB); + + if( !environment.isInstanceRendering()) { + leftViewport = setupViewBuffers(getLeftCamera(), LEFT_VIEW_NAME); + rightCamera = getLeftCamera().clone(); + if( environment.getVRHardware() != null ){ + getRightCamera().setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionRightEye(getRightCamera())); + } + rightViewport = setupViewBuffers(getRightCamera(), RIGHT_VIEW_NAME); + } else { + + if (environment.getApplication() != null){ + + logger.severe("THIS CODE NEED CHANGES !!!"); + leftViewport = environment.getApplication().getViewPort(); + //leftViewport.attachScene(app.getRootNode()); + rightCamera = getLeftCamera().clone(); + if( environment.getVRHardware() != null ){ + getRightCamera().setProjectionMatrix(environment.getVRHardware().getHMDMatrixProjectionRightEye(getRightCamera())); + } + + org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_CLIP_DISTANCE0); + + //FIXME: [jme-vr] Fix with JMonkey next release + //RenderManager._VRInstancing_RightCamProjection = camRight.getViewProjectionMatrix(); + setupFinalFullTexture(environment.getApplication().getViewPort().getCamera()); + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + + } + + // setup gui + environment.getVRGUIManager().setupGui(getLeftCamera(), getRightCamera(), getLeftViewport(), getRightViewport()); + + if( environment.getVRHardware() != null ) { + // call these to cache the results internally + environment.getVRHardware().getHMDMatrixPoseLeftEye(); + environment.getVRHardware().getHMDMatrixPoseRightEye(); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + private ViewPort setupMirrorBuffers(Camera cam, Texture tex, boolean expand) { + + if (environment != null){ + if (environment.getApplication() != null){ + Camera clonecam = cam.clone(); + ViewPort viewPort = environment.getApplication().getRenderManager().createPostView("MirrorView", clonecam); + clonecam.setParallelProjection(true); + viewPort.setClearFlags(true, true, true); + viewPort.setBackgroundColor(ColorRGBA.Black); + Picture pic = new Picture("fullscene"); + pic.setLocalTranslation(-0.75f, -0.5f, 0f); + if( expand ) { + pic.setLocalScale(3f, 1f, 1f); + } else { + pic.setLocalScale(1.5f, 1f, 1f); + } + pic.setQueueBucket(Bucket.Opaque); + pic.setTexture(environment.getApplication().getAssetManager(), (Texture2D)tex, false); + viewPort.attachScene(pic); + viewPort.setOutputFrameBuffer(null); + + pic.updateGeometricState(); + + return viewPort; + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + private void setupFinalFullTexture(Camera cam) { + + if (environment != null){ + if (environment.getApplication() != null){ + // create offscreen framebuffer + FrameBuffer out = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); + //offBuffer.setSrgb(true); + + //setup framebuffer's texture + dualEyeTex = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); + dualEyeTex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); + dualEyeTex.setMagFilter(Texture.MagFilter.Bilinear); + + logger.config("Dual eye texture "+dualEyeTex.getName()+" ("+dualEyeTex.getImage().getId()+")"); + logger.config(" Type: "+dualEyeTex.getType()); + logger.config(" Size: "+dualEyeTex.getImage().getWidth()+"x"+dualEyeTex.getImage().getHeight()); + logger.config(" Image depth: "+dualEyeTex.getImage().getDepth()); + logger.config(" Image format: "+dualEyeTex.getImage().getFormat()); + logger.config(" Image color space: "+dualEyeTex.getImage().getColorSpace()); + + //setup framebuffer to use texture + out.setDepthBuffer(Image.Format.Depth); + out.setColorTexture(dualEyeTex); + + ViewPort viewPort = environment.getApplication().getViewPort(); + viewPort.setClearFlags(true, true, true); + viewPort.setBackgroundColor(ColorRGBA.Black); + viewPort.setOutputFrameBuffer(out); + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + private ViewPort setupViewBuffers(Camera cam, String viewName){ + + if (environment != null){ + if (environment.getApplication() != null){ + // create offscreen framebuffer + FrameBuffer offBufferLeft = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); + //offBufferLeft.setSrgb(true); + + //setup framebuffer's texture + Texture2D offTex = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); + offTex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); + offTex.setMagFilter(Texture.MagFilter.Bilinear); + + //setup framebuffer to use texture + offBufferLeft.setDepthBuffer(Image.Format.Depth); + offBufferLeft.setColorTexture(offTex); + + ViewPort viewPort = environment.getApplication().getRenderManager().createPreView(viewName, cam); + viewPort.setClearFlags(true, true, true); + viewPort.setBackgroundColor(ColorRGBA.Black); + + Iterator spatialIter = environment.getApplication().getViewPort().getScenes().iterator(); + while(spatialIter.hasNext()){ + viewPort.attachScene(spatialIter.next()); + } + + //set viewport to render to offscreen framebuffer + viewPort.setOutputFrameBuffer(offBufferLeft); + return viewPort; + } else { + throw new IllegalStateException("This VR environment is not attached to any application."); + } + } else { + throw new IllegalStateException("This VR view manager is not attached to any VR environment."); + } + } + + /** + * Setup a distortion mesh for the stereo view. + * @param eye the eye to apply. + * @param api the underlying VR api + * @return the distorted mesh. + */ + public static Mesh setupDistortionMesh(int eye, VRAPI api) { + Mesh distortionMesh = new Mesh(); + float m_iLensGridSegmentCountH = 43, m_iLensGridSegmentCountV = 43; + + float w = 1f / (m_iLensGridSegmentCountH - 1f); + float h = 1f / (m_iLensGridSegmentCountV - 1f); + + float u, v; + + float verts[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 3]; + + float texcoordR[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; + float texcoordG[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; + float texcoordB[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; + + int vertPos = 0, coordPos = 0; + + float Xoffset = eye == JOpenVRLibrary.EVREye.EVREye_Eye_Left ? -1f : 0; + for (int y = 0; y < m_iLensGridSegmentCountV; y++) { + for (int x = 0; x < m_iLensGridSegmentCountH; x++) { + u = x * w; + v = 1 - y * h; + verts[vertPos] = Xoffset + u; // x + verts[vertPos + 1] = -1 + 2 * y * h; // y + verts[vertPos + 2] = 0f; // z + vertPos += 3; + + DistortionCoordinates_t dc0 = new DistortionCoordinates_t(); + if( api.getVRSystem() == null ) { + // default to no distortion + texcoordR[coordPos] = u; + texcoordR[coordPos + 1] = 1 - v; + texcoordG[coordPos] = u; + texcoordG[coordPos + 1] = 1 - v; + texcoordB[coordPos] = u; + texcoordB[coordPos + 1] = 1 - v; + } else { + ((VR_IVRSystem_FnTable)api.getVRSystem()).ComputeDistortion.apply(eye, u, v, dc0); + + texcoordR[coordPos] = dc0.rfRed[0]; + texcoordR[coordPos + 1] = 1 - dc0.rfRed[1]; + texcoordG[coordPos] = dc0.rfGreen[0]; + texcoordG[coordPos + 1] = 1 - dc0.rfGreen[1]; + texcoordB[coordPos] = dc0.rfBlue[0]; + texcoordB[coordPos + 1] = 1 - dc0.rfBlue[1]; + } + + coordPos += 2; + } + } + + // have UV coordinates & positions, now to setup indices + + int[] indices = new int[(int) ((m_iLensGridSegmentCountV - 1) * (m_iLensGridSegmentCountH - 1)) * 6]; + int indexPos = 0; + int a, b, c, d; + + int offset = 0; + for (int y = 0; y < m_iLensGridSegmentCountV - 1; y++) { + for (int x = 0; x < m_iLensGridSegmentCountH - 1; x++) { + a = (int) (m_iLensGridSegmentCountH * y + x + offset); + b = (int) (m_iLensGridSegmentCountH * y + x + 1 + offset); + c = (int) ((y + 1) * m_iLensGridSegmentCountH + x + 1 + offset); + d = (int) ((y + 1) * m_iLensGridSegmentCountH + x + offset); + + indices[indexPos] = a; + indices[indexPos + 1] = b; + indices[indexPos + 2] = c; + + indices[indexPos + 3] = a; + indices[indexPos + 4] = c; + indices[indexPos + 5] = d; + + indexPos += 6; + } + } + + // OK, create the mesh + distortionMesh.setBuffer(VertexBuffer.Type.Position, 3, verts); + distortionMesh.setBuffer(VertexBuffer.Type.Index, 1, indices); + distortionMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, texcoordR); + distortionMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, texcoordG); + distortionMesh.setBuffer(VertexBuffer.Type.TexCoord3, 2, texcoordB); + distortionMesh.setStatic(); + return distortionMesh; + } +} diff --git a/jme3-vr/src/main/java/jmevr/util/MeshUtil.java b/jme3-vr/src/main/java/jmevr/util/MeshUtil.java deleted file mode 100644 index 508f33e6b..000000000 --- a/jme3-vr/src/main/java/jmevr/util/MeshUtil.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package jmevr.util; - -import com.jme3.app.VRApplication; -import com.jme3.input.vr.VRAPI; -import com.jme3.scene.Mesh; -import com.jme3.scene.VertexBuffer; -import com.jme3.system.jopenvr.DistortionCoordinates_t; -import com.jme3.system.jopenvr.JOpenVRLibrary; -import com.jme3.system.jopenvr.VR_IVRSystem_FnTable; - -/** - * - * @author reden - */ -public class MeshUtil { - - public static Mesh setupDistortionMesh(int eye, VRAPI api) { - Mesh distortionMesh = new Mesh(); - float m_iLensGridSegmentCountH = 43, m_iLensGridSegmentCountV = 43; - - float w = 1f / (m_iLensGridSegmentCountH - 1f); - float h = 1f / (m_iLensGridSegmentCountV - 1f); - - float u, v; - - float verts[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 3]; - - float texcoordR[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; - float texcoordG[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; - float texcoordB[] = new float[(int) (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2]; - - int vertPos = 0, coordPos = 0; - - float Xoffset = eye == JOpenVRLibrary.EVREye.EVREye_Eye_Left ? -1f : 0; - for (int y = 0; y < m_iLensGridSegmentCountV; y++) { - for (int x = 0; x < m_iLensGridSegmentCountH; x++) { - u = x * w; - v = 1 - y * h; - verts[vertPos] = Xoffset + u; // x - verts[vertPos + 1] = -1 + 2 * y * h; // y - verts[vertPos + 2] = 0f; // z - vertPos += 3; - - DistortionCoordinates_t dc0 = new DistortionCoordinates_t(); - if( api.getVRSystem() == null ) { - // default to no distortion - texcoordR[coordPos] = u; - texcoordR[coordPos + 1] = 1 - v; - texcoordG[coordPos] = u; - texcoordG[coordPos + 1] = 1 - v; - texcoordB[coordPos] = u; - texcoordB[coordPos + 1] = 1 - v; - } else { - ((VR_IVRSystem_FnTable)api.getVRSystem()).ComputeDistortion.apply(eye, u, v, dc0); - - texcoordR[coordPos] = dc0.rfRed[0]; - texcoordR[coordPos + 1] = 1 - dc0.rfRed[1]; - texcoordG[coordPos] = dc0.rfGreen[0]; - texcoordG[coordPos + 1] = 1 - dc0.rfGreen[1]; - texcoordB[coordPos] = dc0.rfBlue[0]; - texcoordB[coordPos + 1] = 1 - dc0.rfBlue[1]; - } - - coordPos += 2; - } - } - - // have UV coordinates & positions, now to setup indices - - int[] indices = new int[(int) ((m_iLensGridSegmentCountV - 1) * (m_iLensGridSegmentCountH - 1)) * 6]; - int indexPos = 0; - int a, b, c, d; - - int offset = 0; - for (int y = 0; y < m_iLensGridSegmentCountV - 1; y++) { - for (int x = 0; x < m_iLensGridSegmentCountH - 1; x++) { - a = (int) (m_iLensGridSegmentCountH * y + x + offset); - b = (int) (m_iLensGridSegmentCountH * y + x + 1 + offset); - c = (int) ((y + 1) * m_iLensGridSegmentCountH + x + 1 + offset); - d = (int) ((y + 1) * m_iLensGridSegmentCountH + x + offset); - - indices[indexPos] = a; - indices[indexPos + 1] = b; - indices[indexPos + 2] = c; - - indices[indexPos + 3] = a; - indices[indexPos + 4] = c; - indices[indexPos + 5] = d; - - indexPos += 6; - } - } - - // OK, create the mesh - distortionMesh.setBuffer(VertexBuffer.Type.Position, 3, verts); - distortionMesh.setBuffer(VertexBuffer.Type.Index, 1, indices); - distortionMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, texcoordR); - distortionMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, texcoordG); - distortionMesh.setBuffer(VertexBuffer.Type.TexCoord3, 2, texcoordB); - distortionMesh.setStatic(); - return distortionMesh; - } -} diff --git a/jme3-vr/src/main/java/jmevr/util/VRGuiManager.java b/jme3-vr/src/main/java/jmevr/util/VRGuiManager.java deleted file mode 100644 index b53b381d0..000000000 --- a/jme3-vr/src/main/java/jmevr/util/VRGuiManager.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package jmevr.util; - -import com.jme3.app.Application; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; -import com.jme3.app.state.AppState; -import com.jme3.material.Material; -import com.jme3.material.RenderState.BlendMode; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Matrix3f; -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.renderer.queue.RenderQueue.Bucket; -import com.jme3.scene.Spatial; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.system.AppSettings; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image.Format; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import java.awt.GraphicsEnvironment; -import java.util.Iterator; - -/** - * - * @author - * phr00t - */ -public class VRGuiManager { - - public enum POSITIONING_MODE { - MANUAL, AUTO_CAM_ALL, AUTO_CAM_ALL_SKIP_PITCH, AUTO_OBSERVER_POS_CAM_ROTATION, AUTO_OBSERVER_ALL, AUTO_OBSERVER_ALL_CAMHEIGHT - } - - private Camera camLeft, camRight; - private float guiDistance = 1.5f, guiScale = 1f, guiPositioningElastic; - private POSITIONING_MODE posMode = POSITIONING_MODE.AUTO_CAM_ALL; - - private final Matrix3f orient = new Matrix3f(); - private Vector2f screenSize; - protected boolean wantsReposition; - - private VRAppState app = null; - private Application application = null; - - /** - * Create a new GUI manager attached to the given app state. - * @param app the VR app state that this manager is attached to. - */ - public VRGuiManager(){ - } - - /** - * Get the VR app state to which this GUI manager is attached. - * @return the VR app state to which this GUI manager is attached. - */ - public VRAppState getVRAppState(){ - return app; - } - - /** - * Attach the GUI manager to an app state and an Application. - * The application has to be the one that the app state is attached. - * This method should be called from the {@link AppState#initialize(com.jme3.app.state.AppStateManager, Application) initialize} - * method of the {@link AppState} instance. - * @param app the VR app state that this manager is attached to. - * @param application the application to whitch the app state is attcached. - */ - public void attach(VRAppState app, Application application){ - this.app = app; - this.application = application; - } - - /** - * - * Makes auto GUI positioning happen not immediately, but like an - * elastic connected to the headset. Setting to 0 disables (default) - * Higher settings make it track the headset quicker. - * - * @param elastic amount of elasticity - */ - public void setPositioningElasticity(float elastic) { - guiPositioningElastic = elastic; - } - - public float getPositioningElasticity() { - return guiPositioningElastic; - } - - public void setPositioningMode(POSITIONING_MODE mode) { - posMode = mode; - } - - public Vector2f getCanvasSize() { - if( screenSize == null ) { - if( app.isInVR() && app.getVRHardware() != null ) { - screenSize = new Vector2f(); - app.getVRHardware().getRenderSize(screenSize); - screenSize.multLocal(app.getVRViewManager().getResolutionMuliplier()); - } else { - AppSettings as = application.getContext().getSettings(); - screenSize = new Vector2f(as.getWidth(), as.getHeight()); - } - } - return screenSize; - } - - private Vector2f ratio; - - public Vector2f getCanvasToWindowRatio() { - if( ratio == null ) { - ratio = new Vector2f(); - Vector2f canvas = getCanvasSize(); - int width = Integer.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getWidth(), - application.getContext().getSettings().getWidth()); - int height = Integer.min(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getHeight(), - application.getContext().getSettings().getHeight()); - ratio.x = Float.max(1f, canvas.x / width); - ratio.y = Float.max(1f, canvas.y / height); - } - return ratio; - } - - public POSITIONING_MODE getPositioningMode() { - return posMode; - } - - public void positionGui() { - wantsReposition = true; - } - - private final Vector3f EoldPos = new Vector3f(); - private final Quaternion EoldDir = new Quaternion(); - private void positionTo(Vector3f pos, Quaternion dir, float tpf) { - Vector3f guiPos = guiQuadNode.getLocalTranslation(); - guiPos.set(0f, 0f, guiDistance); - dir.mult(guiPos, guiPos); - guiPos.x += pos.x; - guiPos.y += pos.y + app.getVRHeightAdjustment(); - guiPos.z += pos.z; - if( guiPositioningElastic > 0f && posMode != POSITIONING_MODE.MANUAL ) { - // mix pos & dir with current pos & dir - guiPos.interpolateLocal(EoldPos, guiPos, Float.min(1f, tpf * guiPositioningElastic)); - EoldPos.set(guiPos); - } - } - - protected void updateGuiQuadGeometricState() { - guiQuadNode.updateGeometricState(); - } - - protected void positionGuiNow(float tpf) { - wantsReposition = false; - if( app.isInVR() == false ) return; - guiQuadNode.setLocalScale(guiDistance * guiScale * 4f, 4f * guiDistance * guiScale, 1f); - - switch( posMode ) { - case MANUAL: - case AUTO_CAM_ALL_SKIP_PITCH: - case AUTO_CAM_ALL: - if( camLeft != null && camRight != null ) { - // get middle point - temppos.set(camLeft.getLocation()).interpolateLocal(camRight.getLocation(), 0.5f); - positionTo(temppos, camLeft.getRotation(), tpf); - } - rotateScreenTo(camLeft.getRotation(), tpf); - - break; - case AUTO_OBSERVER_POS_CAM_ROTATION: - Object obs = app.getObserver(); - if( obs != null ) { - if( obs instanceof Camera ) { - positionTo(((Camera)obs).getLocation(), camLeft.getRotation(), tpf); - } else { - positionTo(((Spatial)obs).getWorldTranslation(), camLeft.getRotation(), tpf); - } - } - rotateScreenTo(camLeft.getRotation(), tpf); - - break; - case AUTO_OBSERVER_ALL: - case AUTO_OBSERVER_ALL_CAMHEIGHT: - obs = app.getObserver(); - if( obs != null ) { - Quaternion q; - if( obs instanceof Camera ) { - q = ((Camera)obs).getRotation(); - temppos.set(((Camera)obs).getLocation()); - } else { - q = ((Spatial)obs).getWorldRotation(); - temppos.set(((Spatial)obs).getWorldTranslation()); - } - if( posMode == POSITIONING_MODE.AUTO_OBSERVER_ALL_CAMHEIGHT ) { - temppos.y = camLeft.getLocation().y; - } - positionTo(temppos, q, tpf); - rotateScreenTo(q, tpf); - - } - break; - - } - - - } - - private final Vector3f look = new Vector3f(), left = new Vector3f(), temppos = new Vector3f(), up = new Vector3f(); - private final Quaternion tempq = new Quaternion(); - - private void rotateScreenTo(Quaternion dir, float tpf) { - dir.getRotationColumn(2, look).negateLocal(); - dir.getRotationColumn(0, left).negateLocal(); - orient.fromAxes(left, dir.getRotationColumn(1, up), look); - Quaternion rot = tempq.fromRotationMatrix(orient); - if( posMode == POSITIONING_MODE.AUTO_CAM_ALL_SKIP_PITCH ) VRUtil.stripToYaw(rot); - if( guiPositioningElastic > 0f && posMode != POSITIONING_MODE.MANUAL ) { - // mix pos & dir with current pos & dir - EoldDir.nlerp(rot, tpf * guiPositioningElastic); - guiQuadNode.setLocalRotation(EoldDir); - } else { - guiQuadNode.setLocalRotation(rot); - } - } - - public void setGuiDistance(float newGuiDistance) { - guiDistance = newGuiDistance; - } - - public void setGuiScale(float scale) { - guiScale = scale; - } - - public float getGuiDistance() { - return guiDistance; - } - - public void adjustGuiDistance(float adjustAmount) { - guiDistance += adjustAmount; - } - - protected void setupGui(Camera leftcam, Camera rightcam, ViewPort left, ViewPort right) { - if( app.hasTraditionalGUIOverlay() ) { - camLeft = leftcam; - camRight = rightcam; - Spatial guiScene = getGuiQuad(camLeft); - left.attachScene(guiScene); - if( right != null ) right.attachScene(guiScene); - setPositioningMode(posMode); - } - } - - /* - do not use, set by preconfigure routine in VRApplication - */ - public void _enableCurvedSuface(boolean set) { - useCurvedSurface = set; - } - - /* - do not use, set by preconfigure routine in VRApplication - */ - public void _enableGuiOverdraw(boolean set) { - overdraw = set; - } - - private boolean useCurvedSurface = false, overdraw = false; - private Geometry guiQuad; - private Node guiQuadNode; - private ViewPort offView; - private Texture2D guiTexture; - - private Spatial getGuiQuad(Camera sourceCam){ - if( guiQuadNode == null ) { - Vector2f guiCanvasSize = getCanvasSize(); - Camera offCamera = sourceCam.clone(); - offCamera.setParallelProjection(true); - offCamera.setLocation(Vector3f.ZERO); - offCamera.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y); - - offView = application.getRenderManager().createPreView("GUI View", offCamera); - offView.setClearFlags(true, true, true); - offView.setBackgroundColor(ColorRGBA.BlackNoAlpha); - - // create offscreen framebuffer - FrameBuffer offBuffer = new FrameBuffer((int)guiCanvasSize.x, (int)guiCanvasSize.y, 1); - - //setup framebuffer's texture - guiTexture = new Texture2D((int)guiCanvasSize.x, (int)guiCanvasSize.y, Format.RGBA8); - guiTexture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); - guiTexture.setMagFilter(Texture.MagFilter.Bilinear); - - //setup framebuffer to use texture - offBuffer.setDepthBuffer(Format.Depth); - offBuffer.setColorTexture(guiTexture); - - //set viewport to render to offscreen framebuffer - offView.setOutputFrameBuffer(offBuffer); - - // setup framebuffer's scene - Iterator spatialIter = application.getGuiViewPort().getScenes().iterator(); - while(spatialIter.hasNext()){ - offView.attachScene(spatialIter.next()); - } - - - if( useCurvedSurface ) { - guiQuad = (Geometry)application.getAssetManager().loadModel("Common/Util/gui_mesh.j3o"); - } else { - guiQuad = new Geometry("guiQuad", new CenterQuad(1f, 1f)); - } - - Material mat = new Material(application.getAssetManager(), "Common/MatDefs/VR/GuiOverlay.j3md"); - mat.getAdditionalRenderState().setDepthTest(!overdraw); - mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); - mat.getAdditionalRenderState().setDepthWrite(false); - mat.setTexture("ColorMap", guiTexture); - guiQuad.setQueueBucket(Bucket.Translucent); - guiQuad.setMaterial(mat); - - guiQuadNode = new Node("gui-quad-node"); - guiQuadNode.setQueueBucket(Bucket.Translucent); - guiQuadNode.attachChild(guiQuad); - } - return guiQuadNode; - } -} diff --git a/jme3-vr/src/main/java/jmevr/util/VRMouseManager.java b/jme3-vr/src/main/java/jmevr/util/VRMouseManager.java deleted file mode 100644 index 5dbcd04ac..000000000 --- a/jme3-vr/src/main/java/jmevr/util/VRMouseManager.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package jmevr.util; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.lwjgl.glfw.GLFW; - -import com.jme3.app.Application; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; -import com.jme3.app.state.AppState; -import com.jme3.input.MouseInput; -import com.jme3.input.controls.AnalogListener; -import com.jme3.input.lwjgl.GlfwMouseInputVR; -import com.jme3.input.vr.VRInputType; -import com.jme3.material.RenderState.BlendMode; -import com.jme3.math.Vector2f; -import com.jme3.scene.Node; -import com.jme3.system.AppSettings; -import com.jme3.system.lwjgl.LwjglWindow; -import com.jme3.system.lwjgl.LwjglWindowVR; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import com.jme3.ui.Picture; - -/** - * - * @author Phr00t - */ -public class VRMouseManager { - - private static final Logger logger = Logger.getLogger(VRMouseManager.class.getName()); - - private Application application = null; - private VRAppState app = null; - - private final int AVERAGE_AMNT = 4; - private int avgCounter; - - private Picture mouseImage; - private int recentCenterCount = 0; - private final Vector2f cursorPos = new Vector2f(); - private float ySize, sensitivity = 8f, acceleration = 2f; - private final float[] lastXmv = new float[AVERAGE_AMNT], lastYmv = new float[AVERAGE_AMNT]; - private boolean thumbstickMode; - private float moveScale = 1f; - - private float avg(float[] arr) { - float amt = 0f; - for(float f : arr) amt += f; - return amt / arr.length; - } - - public VRMouseManager(){ - } - - /** - * Attach the mouse manager to an app state and an Application. - * The application has to be the one that the app state is attached. - * This method should be called from the {@link AppState#initialize(com.jme3.app.state.AppStateManager, Application) initialize} - * method of the {@link AppState} instance. - * @param app the VR app state that this manager is attached to. - * @param application the application to whitch the app state is attcached. - */ - public void attach(VRAppState app, Application application){ - this.app = app; - this.application = application; - } - - protected void init() { - - logger.config("Initializing VR mouse manager."); - - // load default mouseimage - mouseImage = new Picture("mouse"); - setImage("Common/Util/mouse.png"); - // hide default cursor by making it invisible - MouseInput mi = application.getContext().getMouseInput(); - if( mi instanceof GlfwMouseInputVR ){ - ((GlfwMouseInputVR)mi).hideActiveCursor(); - } - centerMouse(); - - logger.config("Initialized VR mouse manager [SUCCESS]"); - } - - public void setThumbstickMode(boolean set) { - thumbstickMode = set; - } - - public boolean isThumbstickMode() { - return thumbstickMode; - } - - public void setSpeed(float sensitivity, float acceleration) { - this.sensitivity = sensitivity; - this.acceleration = acceleration; - } - - public float getSpeedSensitivity() { - return sensitivity; - } - - public float getSpeedAcceleration() { - return acceleration; - } - - public void setMouseMoveScale(float set) { - moveScale = set; - } - - public void setImage(String texture) { - if( app.isInVR() == false ){ - Texture tex = application.getAssetManager().loadTexture(texture); - mouseImage.setTexture(application.getAssetManager(), (Texture2D)tex, true); - ySize = tex.getImage().getHeight(); - mouseImage.setHeight(ySize); - mouseImage.setWidth(tex.getImage().getWidth()); - mouseImage.getMaterial().getAdditionalRenderState().setBlendMode(BlendMode.Alpha); - mouseImage.getMaterial().getAdditionalRenderState().setDepthWrite(false); - } else { - Texture tex = application.getAssetManager().loadTexture(texture); - mouseImage.setTexture(application.getAssetManager(), (Texture2D)tex, true); - ySize = tex.getImage().getHeight(); - mouseImage.setHeight(ySize); - mouseImage.setWidth(tex.getImage().getWidth()); - mouseImage.getMaterial().getAdditionalRenderState().setBlendMode(BlendMode.Alpha); - mouseImage.getMaterial().getAdditionalRenderState().setDepthWrite(false); - } - - } - - public void updateAnalogAsMouse(int inputIndex, AnalogListener mouseListener, String mouseXName, String mouseYName, float tpf) { - // got a tracked controller to use as the "mouse" - if( app.isInVR() == false || - app.getVRinput() == null || - app.getVRinput().isInputDeviceTracking(inputIndex) == false ) return; - Vector2f tpDelta; - if( thumbstickMode ) { - tpDelta = app.getVRinput().getAxis(inputIndex, VRInputType.ViveTrackpadAxis); - } else { - tpDelta = app.getVRinput().getAxisDeltaSinceLastCall(inputIndex, VRInputType.ViveTrackpadAxis); - } - float Xamount = (float)Math.pow(Math.abs(tpDelta.x) * sensitivity, acceleration); - float Yamount = (float)Math.pow(Math.abs(tpDelta.y) * sensitivity, acceleration); - if( tpDelta.x < 0f ) Xamount = -Xamount; - if( tpDelta.y < 0f ) Yamount = -Yamount; - Xamount *= moveScale; Yamount *= moveScale; - if( mouseListener != null ) { - if( tpDelta.x != 0f && mouseXName != null ) mouseListener.onAnalog(mouseXName, Xamount * 0.2f, tpf); - if( tpDelta.y != 0f && mouseYName != null ) mouseListener.onAnalog(mouseYName, Yamount * 0.2f, tpf); - } - if( application.getInputManager().isCursorVisible() ) { - int index = (avgCounter+1) % AVERAGE_AMNT; - lastXmv[index] = Xamount * 133f; - lastYmv[index] = Yamount * 133f; - cursorPos.x -= avg(lastXmv); - cursorPos.y -= avg(lastYmv); - Vector2f maxsize = app.getVRGUIManager().getCanvasSize(); - if( cursorPos.x > maxsize.x ) cursorPos.x = maxsize.x; - if( cursorPos.x < 0f ) cursorPos.x = 0f; - if( cursorPos.y > maxsize.y ) cursorPos.y = maxsize.y; - if( cursorPos.y < 0f ) cursorPos.y = 0f; - } - } - - public Vector2f getCursorPosition() { - if( app.isInVR() ) { - return cursorPos; - } - return application.getInputManager().getCursorPosition(); - } - - public void centerMouse() { - // set mouse in center of the screen if newly added - Vector2f size = app.getVRGUIManager().getCanvasSize(); - MouseInput mi = application.getContext().getMouseInput(); - AppSettings as = application.getContext().getSettings(); - if( mi instanceof GlfwMouseInputVR ) ((GlfwMouseInputVR)mi).setCursorPosition((int)(as.getWidth() / 2f), (int)(as.getHeight() / 2f)); - if( app.isInVR() ) { - cursorPos.x = size.x / 2f; - cursorPos.y = size.y / 2f; - recentCenterCount = 2; - } - } - - protected void update(float tpf) { - // if we are showing the cursor, add our picture as it - - if( application.getInputManager().isCursorVisible() ) { - if( mouseImage.getParent() == null ) { - - application.getGuiViewPort().attachScene(mouseImage); - centerMouse(); - // the "real" mouse pointer should stay hidden - if (application.getContext() instanceof LwjglWindow){ - GLFW.glfwSetInputMode(((LwjglWindow)application.getContext()).getWindowHandle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_DISABLED); - } - } - // handle mouse movements, which may be in addition to (or exclusive from) tracked movement - MouseInput mi = application.getContext().getMouseInput(); - if( mi instanceof GlfwMouseInputVR ) { - if( recentCenterCount <= 0 ) { - //Vector2f winratio = VRGuiManager.getCanvasToWindowRatio(); - cursorPos.x += ((GlfwMouseInputVR)mi).getLastDeltaX();// * winratio.x; - cursorPos.y += ((GlfwMouseInputVR)mi).getLastDeltaY();// * winratio.y; - if( cursorPos.x < 0f ) cursorPos.x = 0f; - if( cursorPos.y < 0f ) cursorPos.y = 0f; - if( cursorPos.x > app.getVRGUIManager().getCanvasSize().x ) cursorPos.x = app.getVRGUIManager().getCanvasSize().x; - if( cursorPos.y > app.getVRGUIManager().getCanvasSize().y ) cursorPos.y = app.getVRGUIManager().getCanvasSize().y; - } else recentCenterCount--; - ((GlfwMouseInputVR)mi).clearDeltas(); - } - // ok, update the cursor graphic position - Vector2f currentPos = getCursorPosition(); - mouseImage.setLocalTranslation(currentPos.x, currentPos.y - ySize, app.getVRGUIManager().getGuiDistance() + 1f); - - mouseImage.updateGeometricState(); - - } else if( mouseImage.getParent() != null ) { - Node n = mouseImage.getParent(); - mouseImage.removeFromParent(); - - if (n != null){ - n.updateGeometricState(); - } - } - } -} diff --git a/jme3-vr/src/main/java/jmevr/util/VRViewManager.java b/jme3-vr/src/main/java/jmevr/util/VRViewManager.java deleted file mode 100644 index 4878a42ab..000000000 --- a/jme3-vr/src/main/java/jmevr/util/VRViewManager.java +++ /dev/null @@ -1,863 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package jmevr.util; - -import com.jme3.app.Application; -import com.jme3.app.VRAppState; -import com.jme3.app.VRApplication; -import com.jme3.app.state.AppState; -import com.jme3.input.vr.OSVR; -import com.jme3.input.vr.OpenVR; -import com.jme3.input.vr.VRAPI; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.post.CartoonSSAO; -import com.jme3.post.Filter; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.SceneProcessor; -import com.jme3.post.filters.FogFilter; -import com.jme3.post.filters.TranslucentBucketFilter; -import com.jme3.post.ssao.SSAOFilter; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.renderer.queue.RenderQueue.Bucket; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.shadow.DirectionalLightShadowFilter; -import com.jme3.shadow.VRDirectionalLightShadowRenderer; -import com.jme3.system.jopenvr.JOpenVRLibrary; -import com.jme3.system.jopenvr.OpenVRUtil; -import com.jme3.system.jopenvr.Texture_t; -import com.jme3.system.jopenvr.VRTextureBounds_t; -import com.jme3.system.lwjgl.LwjglWindow; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import com.jme3.ui.Picture; -import com.sun.jna.Pointer; -import com.sun.jna.ptr.PointerByReference; - -import java.awt.GraphicsEnvironment; -import java.util.Iterator; -import java.util.logging.Logger; - -import osvrrendermanageropengl.OSVR_RenderBufferOpenGL; -import osvrrendermanageropengl.OSVR_ViewportDescription; -import osvrrendermanageropengl.OsvrRenderManagerOpenGLLibrary; - -/** - * A VR view manager. This class enable to submit 3D views to the VR compositor. - * @author reden - phr00t - https://github.com/phr00t - * @author Julien Seinturier - (c) 2016 - JOrigin project - http:/www.jorigin.org - */ -public class VRViewManager { - - private static final Logger logger = Logger.getLogger(VRViewManager.class.getName()); - - /** - * The name of the left view. - */ - public final static String LEFT_VIEW_NAME = "Left View"; - - /** - * The name of the right view. - */ - public final static String RIGHT_VIEW_NAME = "Right View"; - - private VRAppState app; - private Application application; - - private Camera leftCamera; - private ViewPort leftViewport; - private FilterPostProcessor leftPostProcessor; - private Texture2D leftEyeTexture; - private Texture2D leftEyeDepth; - - private Camera rightCamera; - private ViewPort rightViewport; - private FilterPostProcessor rightPostProcessor; - private Texture2D rightEyeTexture; - private Texture2D rightEyeDepth; - - // OpenVR values - private VRTextureBounds_t leftTextureBounds; - private Texture_t leftTextureType; - - private VRTextureBounds_t rightTextureBounds; - private Texture_t rightTextureType; - - // OSVR values - OSVR_RenderBufferOpenGL.ByValue[] osvr_renderBuffer; - OSVR_ViewportDescription.ByValue osvr_viewDescFull; - OSVR_ViewportDescription.ByValue osvr_viewDescLeft; - OSVR_ViewportDescription.ByValue osvr_viewDescRight; - Pointer osvr_rmBufferState; - - //private static boolean useCustomDistortion; - private float heightAdjustment; - - private Texture2D dualEyeTex; - - private final PointerByReference grabRBS = new PointerByReference(); - - private float resMult = 1f; - - //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(); - - /** - * Create a new VR view manager attached to the given {@link VRAppState VR app state}.
- * in order to be used, this manager has to be attached to an app state and to an application. - */ - public VRViewManager(){ - } - - /** - * Attach this manager to the given {@link VRAppState app state} and the given {@link Application application}. - * The application has to be the one that the app state is attached. - * This method should be called from the {@link AppState#initialize(com.jme3.app.state.AppStateManager, Application) initialize} - * method of the {@link AppState} instance. - * @param app the {@link VRAppState VR app state} to which this manager is linked. - * @param application the {@link Application} which the app state is attached. - */ - public void attach(VRAppState app, Application application){ - this.app = app; - this.application = application; - } - - /** - * Get the {@link Camera camera} attached to the left eye. - * @return the {@link Camera camera} attached to the left eye. - * @see #getRightCamera() - */ - public Camera getLeftCamera() { - return leftCamera; - } - - /** - * Get the {@link Camera camera} attached to the right eye. - * @return the {@link Camera camera} attached to the right eye. - * @see #getLeftCamera() - */ - public Camera getRightCamera() { - return rightCamera; - } - - /** - * Get the {@link ViewPort viewport} attached to the left eye. - * @return the {@link ViewPort viewport} attached to the left eye. - * @see #getRightViewport() - */ - public ViewPort getLeftViewport() { - return leftViewport; - } - - /** - * Get the {@link ViewPort viewport} attached to the right eye. - * @return the {@link ViewPort viewport} attached to the right eye. - * @see #getLeftViewport() - */ - public ViewPort getRightViewport() { - return rightViewport; - } - - /** - * Get the identifier of the left eye texture. - * @return the identifier of the left eye texture. - * @see #getRightTexId() - * @see #getFullTexId() - */ - private int getLeftTexId() { - return (int)leftEyeTexture.getImage().getId(); - } - - /** - * Get the identifier of the right eye texture. - * @return the identifier of the right eye texture. - * @see #getLeftTexId() - * @see #getFullTexId() - */ - private int getRightTexId() { - return (int)rightEyeTexture.getImage().getId(); - } - - /** - * Get the identifier of the full (dual eye) texture. - * @return the identifier of the full (dual eye) texture. - * @see #getLeftTexId() - * @see #getRightTexId() - */ - private int getFullTexId() { - return (int)dualEyeTex.getImage().getId(); - } - - /** - * Get the height adjustment to apply to the cameras before rendering. - * @return the height adjustment to apply to the cameras before rendering. - * @see #setHeightAdjustment(float) - */ - public float getHeightAdjustment() { - return heightAdjustment; - } - - /** - * Set the height adjustment to apply to the cameras before rendering. - * @param amount the height adjustment to apply to the cameras before rendering. - * @see #getHeightAdjustment() - */ - public void setHeightAdjustment(float amount) { - heightAdjustment = amount; - } - - /** - * Get the resolution multiplier. - * @return the resolution multiplier. - * @see #setResolutionMultiplier(float) - */ - public float getResolutionMuliplier() { - return resMult; - } - - /** - * Set the resolution multiplier. - * @param resMult the resolution multiplier. - * @see #getResolutionMuliplier() - */ - public void setResolutionMultiplier(float resMult) { - this.resMult = resMult; - } - - /** - * Initialize the system binds of the textures. - */ - private void initTextureSubmitStructs() { - leftTextureType = new Texture_t(); - rightTextureType = new Texture_t(); - - - if( app.getVRHardware() instanceof OpenVR ) { - leftTextureBounds = new VRTextureBounds_t(); - rightTextureBounds = new VRTextureBounds_t(); - // left eye - leftTextureBounds.uMax = 0.5f; - leftTextureBounds.uMin = 0f; - leftTextureBounds.vMax = 1f; - leftTextureBounds.vMin = 0f; - leftTextureBounds.setAutoSynch(false); - leftTextureBounds.setAutoRead(false); - leftTextureBounds.setAutoWrite(false); - leftTextureBounds.write(); - // right eye - rightTextureBounds.uMax = 1f; - rightTextureBounds.uMin = 0.5f; - rightTextureBounds.vMax = 1f; - rightTextureBounds.vMin = 0f; - rightTextureBounds.setAutoSynch(false); - rightTextureBounds.setAutoRead(false); - rightTextureBounds.setAutoWrite(false); - rightTextureBounds.write(); - // texture type - // FIXME: Synchronize with JMonkey given texture (at this time is linear but was Gamma with phr00t implementation) - leftTextureType.eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Gamma; - //leftTextureType.eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Linear; - leftTextureType.eType = JOpenVRLibrary.ETextureType.ETextureType_TextureType_OpenGL; - leftTextureType.setAutoSynch(false); - leftTextureType.setAutoRead(false); - leftTextureType.setAutoWrite(false); - leftTextureType.handle = -1; - // FIXME: Synchronize with JMonkey given texture (at this time is linear but was Gamma with phr00t implementation) - rightTextureType.eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Gamma; - //rightTextureType.eColorSpace = JOpenVRLibrary.EColorSpace.EColorSpace_ColorSpace_Linear; - rightTextureType.eType = JOpenVRLibrary.ETextureType.ETextureType_TextureType_OpenGL; - rightTextureType.setAutoSynch(false); - rightTextureType.setAutoRead(false); - rightTextureType.setAutoWrite(false); - rightTextureType.handle = -1; - - - logger.config("Init eyes native texture binds"); - logger.config(" Left eye texture"); - logger.config(" address: "+leftTextureType.getPointer()); - logger.config(" size: "+leftTextureType.size()+" bytes"); - logger.config(" color space: "+OpenVRUtil.getEColorSpaceString(leftTextureType.eColorSpace)); - logger.config(" type: "+OpenVRUtil.getETextureTypeString(leftTextureType.eType)); - logger.config(" auto read: "+leftTextureType.getAutoRead()); - logger.config(" auto write: "+leftTextureType.getAutoWrite()); - logger.config(" handle address: "+leftTextureType.handle); - logger.config(" handle value: "+leftTextureType.handle); - logger.config(""); - logger.config(" Right eye texture"); - logger.config(" address: "+rightTextureType.getPointer()); - logger.config(" size: "+rightTextureType.size()+" bytes"); - logger.config(" color space: "+OpenVRUtil.getEColorSpaceString(rightTextureType.eColorSpace)); - logger.config(" type: "+OpenVRUtil.getETextureTypeString(rightTextureType.eType)); - logger.config(" auto read: "+rightTextureType.getAutoRead()); - logger.config(" auto write: "+rightTextureType.getAutoWrite()); - logger.config(" handle address: "+rightTextureType.handle); - logger.config(" handle value: "+rightTextureType.handle); - - - } else if( app.getVRHardware() instanceof OSVR ) { - // must be OSVR - osvr_renderBuffer = new OSVR_RenderBufferOpenGL.ByValue[2]; - osvr_renderBuffer[OSVR.EYE_LEFT] = new OSVR_RenderBufferOpenGL.ByValue(); - osvr_renderBuffer[OSVR.EYE_RIGHT] = new OSVR_RenderBufferOpenGL.ByValue(); - osvr_renderBuffer[OSVR.EYE_LEFT].setAutoSynch(false); - osvr_renderBuffer[OSVR.EYE_RIGHT].setAutoSynch(false); - osvr_viewDescFull = new OSVR_ViewportDescription.ByValue(); - osvr_viewDescFull.setAutoSynch(false); - osvr_viewDescFull.left = osvr_viewDescFull.lower = 0.0; - osvr_viewDescFull.width = osvr_viewDescFull.height = 1.0; - osvr_viewDescLeft = new OSVR_ViewportDescription.ByValue(); - osvr_viewDescLeft.setAutoSynch(false); - osvr_viewDescLeft.left = osvr_viewDescLeft.lower = 0.0; - osvr_viewDescLeft.width = 0.5; - osvr_viewDescLeft.height = 1.0; - osvr_viewDescRight = new OSVR_ViewportDescription.ByValue(); - osvr_viewDescRight.setAutoSynch(false); - osvr_viewDescRight.left = 0.5; - osvr_viewDescRight.lower = 0.0; - osvr_viewDescRight.width = 0.5; - osvr_viewDescRight.height = 1.0; - osvr_viewDescRight.write(); - osvr_viewDescLeft.write(); - osvr_viewDescFull.write(); - osvr_renderBuffer[OSVR.EYE_LEFT].depthStencilBufferName = -1; - osvr_renderBuffer[OSVR.EYE_LEFT].colorBufferName = -1; - osvr_renderBuffer[OSVR.EYE_RIGHT].depthStencilBufferName = -1; - osvr_renderBuffer[OSVR.EYE_RIGHT].colorBufferName = -1; - } - } - - /** - * Register the OSVR OpenGL buffer. - * @param buf the OSVR OpenGL buffer. - */ - private void registerOSVRBuffer(OSVR_RenderBufferOpenGL.ByValue buf) { - OsvrRenderManagerOpenGLLibrary.osvrRenderManagerStartRegisterRenderBuffers(grabRBS); - OsvrRenderManagerOpenGLLibrary.osvrRenderManagerRegisterRenderBufferOpenGL(grabRBS.getValue(), buf); - OsvrRenderManagerOpenGLLibrary.osvrRenderManagerFinishRegisterRenderBuffers(((OSVR)app.getVRHardware()).getCompositor(), grabRBS.getValue(), (byte)0); - } - - /** - * Send the textures to the two eyes. - */ - public void sendTextures() { - if( app.isInVR() ) { - VRAPI api = app.getVRHardware(); - if( api.getCompositor() != null ) { - // using the compositor... - int errl = 0, errr = 0; - if( app.isInstanceVRRendering() ) { - if( leftTextureType.handle == -1 || leftTextureType.handle != getFullTexId() ) { - leftTextureType.handle = getFullTexId(); - if( leftTextureType.handle != -1 ) { - leftTextureType.write(); - if( api instanceof OSVR ) { - osvr_renderBuffer[OSVR.EYE_LEFT].colorBufferName = leftTextureType.handle; - osvr_renderBuffer[OSVR.EYE_LEFT].depthStencilBufferName = dualEyeTex.getImage().getId(); - osvr_renderBuffer[OSVR.EYE_LEFT].write(); - registerOSVRBuffer(osvr_renderBuffer[OSVR.EYE_LEFT]); - } - } - } else { - if( api instanceof OpenVR ) { - int submitFlag = JOpenVRLibrary.EVRSubmitFlags.EVRSubmitFlags_Submit_Default; - errr = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, leftTextureType, rightTextureBounds, submitFlag); - errl = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, leftTextureType, leftTextureBounds, submitFlag); - } else if( api instanceof OSVR ) { - ((OSVR)api).handleRenderBufferPresent(osvr_viewDescLeft, osvr_viewDescRight, - osvr_renderBuffer[OSVR.EYE_LEFT], osvr_renderBuffer[OSVR.EYE_LEFT]); - } - } - } else if( leftTextureType.handle == -1 || rightTextureType.handle == -1 || - leftTextureType.handle != getLeftTexId() || rightTextureType.handle != getRightTexId() ) { - leftTextureType.handle = getLeftTexId(); - if( leftTextureType.handle != -1 ) { - logger.fine("Writing Left texture to native memory at " + leftTextureType.getPointer()); - leftTextureType.write(); - if( api instanceof OSVR ) { - osvr_renderBuffer[OSVR.EYE_LEFT].colorBufferName = leftTextureType.handle; - if( leftEyeDepth != null ) osvr_renderBuffer[OSVR.EYE_LEFT].depthStencilBufferName = leftEyeDepth.getImage().getId(); - osvr_renderBuffer[OSVR.EYE_LEFT].write(); - registerOSVRBuffer(osvr_renderBuffer[OSVR.EYE_LEFT]); - } - } - rightTextureType.handle = getRightTexId(); - if( rightTextureType.handle != -1 ) { - logger.fine("Writing Right texture to native memory at " + leftTextureType.getPointer()); - rightTextureType.write(); - if( api instanceof OSVR ) { - osvr_renderBuffer[OSVR.EYE_RIGHT].colorBufferName = rightTextureType.handle; - if( rightEyeDepth != null ) osvr_renderBuffer[OSVR.EYE_RIGHT].depthStencilBufferName = rightEyeDepth.getImage().getId(); - osvr_renderBuffer[OSVR.EYE_RIGHT].write(); - registerOSVRBuffer(osvr_renderBuffer[OSVR.EYE_RIGHT]); - } - } - } else { - if( api instanceof OpenVR ) { - errl = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Left, leftTextureType, null, - JOpenVRLibrary.EVRSubmitFlags.EVRSubmitFlags_Submit_Default); - errr = ((OpenVR)api).getCompositor().Submit.apply(JOpenVRLibrary.EVREye.EVREye_Eye_Right, rightTextureType, null, - JOpenVRLibrary.EVRSubmitFlags.EVRSubmitFlags_Submit_Default); - } else if( api instanceof OSVR ) { - ((OSVR)api).handleRenderBufferPresent(osvr_viewDescFull, osvr_viewDescFull, - osvr_renderBuffer[OSVR.EYE_LEFT], osvr_renderBuffer[OSVR.EYE_RIGHT]); - } - } - - if( errl != 0 ){ - logger.severe("Submit to left compositor error: " + OpenVRUtil.getEVRCompositorErrorString(errl)+" ("+Integer.toString(errl)+")"); - logger.severe(" Texture color space: "+OpenVRUtil.getEColorSpaceString(leftTextureType.eColorSpace)); - logger.severe(" Texture type: "+OpenVRUtil.getETextureTypeString(leftTextureType.eType)); - logger.severe(" Texture handle: "+leftTextureType.handle); - - logger.severe(" Left eye texture "+leftEyeTexture.getName()+" ("+leftEyeTexture.getImage().getId()+")"); - logger.severe(" Type: "+leftEyeTexture.getType()); - logger.severe(" Size: "+leftEyeTexture.getImage().getWidth()+"x"+leftEyeTexture.getImage().getHeight()); - logger.severe(" Image depth: "+leftEyeTexture.getImage().getDepth()); - logger.severe(" Image format: "+leftEyeTexture.getImage().getFormat()); - logger.severe(" Image color space: "+leftEyeTexture.getImage().getColorSpace()); - - } - - if( errr != 0 ){ - logger.severe("Submit to right compositor error: " + OpenVRUtil.getEVRCompositorErrorString(errl)+" ("+Integer.toString(errl)+")"); - logger.severe(" Texture color space: "+OpenVRUtil.getEColorSpaceString(rightTextureType.eColorSpace)); - logger.severe(" Texture type: "+OpenVRUtil.getETextureTypeString(rightTextureType.eType)); - logger.severe(" Texture handle: "+rightTextureType.handle); - - logger.severe(" Right eye texture "+rightEyeTexture.getName()+" ("+rightEyeTexture.getImage().getId()+")"); - logger.severe(" Type: "+rightEyeTexture.getType()); - logger.severe(" Size: "+rightEyeTexture.getImage().getWidth()+"x"+rightEyeTexture.getImage().getHeight()); - logger.severe(" Image depth: "+rightEyeTexture.getImage().getDepth()); - logger.severe(" Image format: "+rightEyeTexture.getImage().getFormat()); - logger.severe(" Image color space: "+rightEyeTexture.getImage().getColorSpace()); - } - } - } - } - - - /** - * Initialize the VR view manager. - */ - public void initialize() { - - logger.config("Initializing VR view manager."); - - initTextureSubmitStructs(); - setupCamerasAndViews(); - setupVRScene(); - moveScreenProcessingToEyes(); - if( app.hasTraditionalGUIOverlay() ) { - - app.getVRMouseManager().init(); - - // update the pose to position the gui correctly on start - update(0f); - app.getVRGUIManager().positionGui(); - } - // if we are OSVR, our primary mirror window needs to be the same size as the render manager's output... - if( app.getVRHardware() instanceof OSVR ) { - int origWidth = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getWidth(); - int origHeight = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getHeight(); - long window = ((LwjglWindow)application.getContext()).getWindowHandle(); - Vector2f windowSize = new Vector2f(); - ((OSVR)app.getVRHardware()).getRenderSize(windowSize); - windowSize.x = Math.max(windowSize.x * 2f, leftCamera.getWidth()); - org.lwjgl.glfw.GLFW.glfwSetWindowSize(window, (int)windowSize.x, (int)windowSize.y); - application.getContext().getSettings().setResolution((int)windowSize.x, (int)windowSize.y); - - if (application.getRenderManager() != null) { - application.getRenderManager().notifyReshape((int)windowSize.x, (int)windowSize.y); - } - - org.lwjgl.glfw.GLFW.glfwSetWindowPos(window, origWidth - (int)windowSize.x, 32); - - org.lwjgl.glfw.GLFW.glfwFocusWindow(window); - - org.lwjgl.glfw.GLFW.glfwSetCursorPos(window, origWidth / 2.0, origHeight / 2.0); - } - - logger.config("Initialized VR view manager [SUCCESS]"); - } - - /** - * Prepare the size of the given {@link Camera camera} to adapt it to the underlying rendering context. - * @param cam the {@link Camera camera} to prepare. - * @param xMult the camera width multiplier. - */ - private void prepareCameraSize(Camera cam, float xMult) { - Vector2f size = new Vector2f(); - VRAPI vrhmd = app.getVRHardware(); - - if( vrhmd == null ) { - size.x = 1280f; - size.y = 720f; - } else { - vrhmd.getRenderSize(size); - } - - if( size.x < application.getContext().getSettings().getWidth() ) { - size.x = application.getContext().getSettings().getWidth(); - } - if( size.y < application.getContext().getSettings().getHeight() ) { - size.y = application.getContext().getSettings().getHeight(); - } - - if( app.isInstanceVRRendering() ) size.x *= 2f; - - // other adjustments - size.x *= xMult; - size.x *= resMult; - size.y *= resMult; - - if( cam.getWidth() != size.x || cam.getHeight() != size.y ) cam.resize((int)size.x, (int)size.y, false); - } - - /** - * Replaces rootNode as the main cameras scene with the distortion mesh - */ - private void setupVRScene(){ - // no special scene to setup if we are doing instancing - if( app.isInstanceVRRendering() ) { - // distortion has to be done with compositor here... we want only one pass on our end! - if( application.getContext().getSettings().isSwapBuffers() ) { - setupMirrorBuffers(app.getCamera(), dualEyeTex, true); - } - return; - } - - leftEyeTexture = (Texture2D) leftViewport.getOutputFrameBuffer().getColorBuffer().getTexture(); - rightEyeTexture = (Texture2D)rightViewport.getOutputFrameBuffer().getColorBuffer().getTexture(); - leftEyeDepth = (Texture2D) leftViewport.getOutputFrameBuffer().getDepthBuffer().getTexture(); - rightEyeDepth = (Texture2D)rightViewport.getOutputFrameBuffer().getDepthBuffer().getTexture(); - - // main viewport is either going to be a distortion scene or nothing - // mirroring is handled by copying framebuffers - Iterator spatialIter = application.getViewPort().getScenes().iterator(); - while(spatialIter.hasNext()){ - application.getViewPort().detachScene(spatialIter.next()); - } - - spatialIter = application.getGuiViewPort().getScenes().iterator(); - while(spatialIter.hasNext()){ - application.getGuiViewPort().detachScene(spatialIter.next()); - } - - // only setup distortion scene if compositor isn't running (or using custom mesh distortion option) - if( app.getVRHardware().getCompositor() == null ) { - Node distortionScene = new Node(); - Material leftMat = new Material(application.getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md"); - leftMat.setTexture("Texture", leftEyeTexture); - Geometry leftEye = new Geometry("box", MeshUtil.setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Left, app.getVRHardware())); - leftEye.setMaterial(leftMat); - distortionScene.attachChild(leftEye); - - Material rightMat = new Material(application.getAssetManager(), "Common/MatDefs/VR/OpenVR.j3md"); - rightMat.setTexture("Texture", rightEyeTexture); - Geometry rightEye = new Geometry("box", MeshUtil.setupDistortionMesh(JOpenVRLibrary.EVREye.EVREye_Eye_Right, app.getVRHardware())); - rightEye.setMaterial(rightMat); - distortionScene.attachChild(rightEye); - - distortionScene.updateGeometricState(); - - application.getViewPort().attachScene(distortionScene); - - //if( useCustomDistortion ) setupFinalFullTexture(app.getViewPort().getCamera()); - } - - if( application.getContext().getSettings().isSwapBuffers() ) { - setupMirrorBuffers(app.getCamera(), leftEyeTexture, false); - } - } - - /** - * Update the VR view manager. - * This method is called by the attached {@link VRApplication VR application} and should not be called manually. - * @param tpf the time per frame. - */ - public void update(float tpf) { - - // grab the observer - Object obs = app.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 = app.getVRHardware(); - if( dev != null ) { - // update the HMD's position & orientation - dev.updatePose(); - 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( app.hasTraditionalGUIOverlay() ) { - // update the mouse? - app.getVRMouseManager().update(tpf); - - // update GUI position? - if( app.getVRGUIManager().wantsReposition || app.getVRGUIManager().getPositioningMode() != VRGuiManager.POSITIONING_MODE.MANUAL ) { - app.getVRGUIManager().positionGuiNow(tpf); - app.getVRGUIManager().updateGuiQuadGeometricState(); - } - } - } - - /** - * 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 += heightAdjustment; - cam.setFrame(finalPosition, finalRotation); - } - - /** - * Handles moving filters from the main view to each eye - */ - public void moveScreenProcessingToEyes() { - if( rightViewport == null ) return; - syncScreenProcessing(application.getViewPort()); - application.getViewPort().clearProcessors(); - } - - /** - * Sets the two views to use the list of {@link SceneProcessor processors}. - * @param sourceViewport the {@link ViewPort viewport} that contains the processors to use. - */ - public void syncScreenProcessing(ViewPort sourceViewport) { - if( rightViewport == null ) return; - // setup post processing filters - if( rightPostProcessor == null ) { - rightPostProcessor = new FilterPostProcessor(application.getAssetManager()); - leftPostProcessor = new FilterPostProcessor(application.getAssetManager()); - } - // clear out all filters & processors, to start from scratch - rightPostProcessor.removeAllFilters(); - leftPostProcessor.removeAllFilters(); - leftViewport.clearProcessors(); - rightViewport.clearProcessors(); - // if we have no processors to sync, don't add the FilterPostProcessor - if( sourceViewport.getProcessors().isEmpty() ) return; - // add post processors we just made, which are empty - leftViewport.addProcessor(leftPostProcessor); - rightViewport.addProcessor(rightPostProcessor); - // go through all of the filters in the processors list - // add them to the left viewport processor & clone them to the right - for(SceneProcessor sceneProcessor : sourceViewport.getProcessors()) { - if (sceneProcessor instanceof FilterPostProcessor) { - for(Filter f : ((FilterPostProcessor)sceneProcessor).getFilterList() ) { - if( f instanceof TranslucentBucketFilter ) { - // just remove this filter, we will add it at the end manually - ((FilterPostProcessor)sceneProcessor).removeFilter(f); - } else { - leftPostProcessor.addFilter(f); - // clone to the right - Filter f2; - if(f instanceof FogFilter){ - f2 = FilterUtil.cloneFogFilter((FogFilter)f); - } else if (f instanceof CartoonSSAO ) { - f2 = new CartoonSSAO((CartoonSSAO)f); - } else if (f instanceof SSAOFilter){ - f2 = FilterUtil.cloneSSAOFilter((SSAOFilter)f); - } else if (f instanceof DirectionalLightShadowFilter){ - f2 = FilterUtil.cloneDirectionalLightShadowFilter(application.getAssetManager(), (DirectionalLightShadowFilter)f); - } else { - f2 = f; // dof, bloom, lightscattering etc. - } - rightPostProcessor.addFilter(f2); - } - } - } else if (sceneProcessor instanceof VRDirectionalLightShadowRenderer) { - // shadow processing - // TODO: make right shadow processor use same left shadow maps for performance - VRDirectionalLightShadowRenderer dlsr = (VRDirectionalLightShadowRenderer) sceneProcessor; - VRDirectionalLightShadowRenderer dlsrRight = dlsr.clone(); - dlsrRight.setLight(dlsr.getLight()); - rightViewport.getProcessors().add(0, dlsrRight); - leftViewport.getProcessors().add(0, sceneProcessor); - } - } - // make sure each has a translucent filter renderer - leftPostProcessor.addFilter(new TranslucentBucketFilter()); - rightPostProcessor.addFilter(new TranslucentBucketFilter()); - } - - private void setupCamerasAndViews() { - // get desired frustrum from original camera - Camera origCam = app.getCamera(); - float fFar = origCam.getFrustumFar(); - float fNear = origCam.getFrustumNear(); - - // if we are using OSVR get the eye info here - if( app.getVRHardware() instanceof OSVR ) { - ((OSVR)app.getVRHardware()).getEyeInfo(); - } - - // restore frustrum on distortion scene cam, if needed - if( app.isInstanceVRRendering() ) { - leftCamera = origCam; - } else if( app.compositorAllowed() == false ) { - origCam.setFrustumFar(100f); - origCam.setFrustumNear(1f); - leftCamera = origCam.clone(); - prepareCameraSize(origCam, 2f); - } else { - leftCamera = origCam.clone(); - } - - leftCamera.setFrustumPerspective(app.getDefaultFOV(), app.getDefaultAspect(), fNear, fFar); - - prepareCameraSize(leftCamera, 1f); - if( app.getVRHardware() != null ) leftCamera.setProjectionMatrix(app.getVRHardware().getHMDMatrixProjectionLeftEye(leftCamera)); - //org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_SRGB); - - if( !app.isInstanceVRRendering()) { - leftViewport = setupViewBuffers(leftCamera, LEFT_VIEW_NAME); - rightCamera = leftCamera.clone(); - if( app.getVRHardware() != null ){ - rightCamera.setProjectionMatrix(app.getVRHardware().getHMDMatrixProjectionRightEye(rightCamera)); - } - rightViewport = setupViewBuffers(rightCamera, RIGHT_VIEW_NAME); - } else { - - System.err.println("[VRViewManager] THIS CODE NEED CHANGES !!!"); - leftViewport = application.getViewPort(); - //leftViewport.attachScene(app.getRootNode()); - rightCamera = leftCamera.clone(); - if( app.getVRHardware() != null ){ - rightCamera.setProjectionMatrix(app.getVRHardware().getHMDMatrixProjectionRightEye(rightCamera)); - } - - org.lwjgl.opengl.GL11.glEnable(org.lwjgl.opengl.GL30.GL_CLIP_DISTANCE0); - - //FIXME: [jme-vr] Fix with JMonkey next release - //RenderManager._VRInstancing_RightCamProjection = camRight.getViewProjectionMatrix(); - setupFinalFullTexture(application.getViewPort().getCamera()); - } - - // setup gui - app.getVRGUIManager().setupGui(leftCamera, rightCamera, leftViewport, rightViewport); - - if( app.getVRHardware() != null ) { - // call these to cache the results internally - app.getVRHardware().getHMDMatrixPoseLeftEye(); - app.getVRHardware().getHMDMatrixPoseRightEye(); - } - - } - - private ViewPort setupMirrorBuffers(Camera cam, Texture tex, boolean expand) { - Camera clonecam = cam.clone(); - ViewPort viewPort = application.getRenderManager().createPostView("MirrorView", clonecam); - clonecam.setParallelProjection(true); - viewPort.setClearFlags(true, true, true); - viewPort.setBackgroundColor(ColorRGBA.Black); - Picture pic = new Picture("fullscene"); - pic.setLocalTranslation(-0.75f, -0.5f, 0f); - if( expand ) { - pic.setLocalScale(3f, 1f, 1f); - } else { - pic.setLocalScale(1.5f, 1f, 1f); - } - pic.setQueueBucket(Bucket.Opaque); - pic.setTexture(application.getAssetManager(), (Texture2D)tex, false); - viewPort.attachScene(pic); - viewPort.setOutputFrameBuffer(null); - - pic.updateGeometricState(); - - return viewPort; - } - - private void setupFinalFullTexture(Camera cam) { - // create offscreen framebuffer - FrameBuffer out = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); - //offBuffer.setSrgb(true); - - //setup framebuffer's texture - dualEyeTex = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); - dualEyeTex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); - dualEyeTex.setMagFilter(Texture.MagFilter.Bilinear); - - logger.config("Dual eye texture "+dualEyeTex.getName()+" ("+dualEyeTex.getImage().getId()+")"); - logger.config(" Type: "+dualEyeTex.getType()); - logger.config(" Size: "+dualEyeTex.getImage().getWidth()+"x"+dualEyeTex.getImage().getHeight()); - logger.config(" Image depth: "+dualEyeTex.getImage().getDepth()); - logger.config(" Image format: "+dualEyeTex.getImage().getFormat()); - logger.config(" Image color space: "+dualEyeTex.getImage().getColorSpace()); - - //setup framebuffer to use texture - out.setDepthBuffer(Image.Format.Depth); - out.setColorTexture(dualEyeTex); - - ViewPort viewPort = application.getViewPort(); - viewPort.setClearFlags(true, true, true); - viewPort.setBackgroundColor(ColorRGBA.Black); - viewPort.setOutputFrameBuffer(out); - - } - - private ViewPort setupViewBuffers(Camera cam, String viewName){ - // create offscreen framebuffer - FrameBuffer offBufferLeft = new FrameBuffer(cam.getWidth(), cam.getHeight(), 1); - //offBufferLeft.setSrgb(true); - - //setup framebuffer's texture - Texture2D offTex = new Texture2D(cam.getWidth(), cam.getHeight(), Image.Format.RGBA8); - offTex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps); - offTex.setMagFilter(Texture.MagFilter.Bilinear); - - //setup framebuffer to use texture - offBufferLeft.setDepthBuffer(Image.Format.Depth); - offBufferLeft.setColorTexture(offTex); - - ViewPort viewPort = application.getRenderManager().createPreView(viewName, cam); - viewPort.setClearFlags(true, true, true); - viewPort.setBackgroundColor(ColorRGBA.Black); - - Iterator spatialIter = application.getViewPort().getScenes().iterator(); - while(spatialIter.hasNext()){ - viewPort.attachScene(spatialIter.next()); - } - - //set viewport to render to offscreen framebuffer - viewPort.setOutputFrameBuffer(offBufferLeft); - return viewPort; - } -}