Skip to content

Commit 120f333

Browse files
committed
#1734 Bring the LWJGL OpenVR implementation up to the modern actions based input/vr/AnalogActionState.java
All the other apis are vender specific or are alternative of versions OpenVR, so are deprecated - Deprecate everything but lwjgl openVr - Add support for restricting analog, digital and haptics to a particular hand - improve vr javadocs - Add haptics to the new openVR api - Add analogue inputs - Add action based digital controls into jme-vr
1 parent 25cbaac commit 120f333

File tree

9 files changed

+555
-7
lines changed

9 files changed

+555
-7
lines changed

jme3-vr/src/main/java/com/jme3/app/VRConstants.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,31 @@ public class VRConstants {
123123

124124
/**
125125
* The identifier of the OpenVR system.
126+
*
127+
* Deprecated as only the lwjgl OpenVr version has been upgraded to modern action based inputs
128+
*
126129
* @see #SETTING_VRAPI_OSVR_VALUE
127130
* @see #SETTING_VRAPI_OPENVR_LWJGL_VALUE
128131
* @see #SETTING_VRAPI_OCULUSVR_VALUE
129132
*/
133+
@Deprecated
130134
public static final int SETTING_VRAPI_OPENVR_VALUE = 1;
131135

132136
/**
133137
* The identifier of the OSVR system.
138+
*
139+
* Deprecated as an OpenVr system should be used instead for a non vender specific api
140+
*
134141
* @see #SETTING_VRAPI_OPENVR_VALUE
135142
* @see #SETTING_VRAPI_OPENVR_LWJGL_VALUE
136143
* @see #SETTING_VRAPI_OCULUSVR_VALUE
137144
*/
145+
@Deprecated
138146
public static final int SETTING_VRAPI_OSVR_VALUE = 2;
139147

140148
/**
141149
* The identifier of the OpenVR from LWJGL system.
150+
*
142151
* @see #SETTING_VRAPI_OPENVR_VALUE
143152
* @see #SETTING_VRAPI_OSVR_VALUE
144153
* @see #SETTING_VRAPI_OCULUSVR_VALUE
@@ -147,10 +156,14 @@ public class VRConstants {
147156

148157
/**
149158
* The identifier of the Oculus Rift system.
159+
*
160+
* Deprecated as an OpenVr system should be used instead (and the rift itself is discontinued)
161+
*
150162
* @see #SETTING_VRAPI_OPENVR_VALUE
151163
* @see #SETTING_VRAPI_OSVR_VALUE
152164
* @see #SETTING_VRAPI_OPENVR_LWJGL_VALUE
153165
*/
166+
@Deprecated
154167
public static final int SETTING_VRAPI_OCULUSVR_VALUE = 4;
155168

156169
/**

jme3-vr/src/main/java/com/jme3/app/VREnvironment.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ private void processSettings(){
513513

514514
if (settings.get(VRConstants.SETTING_VRAPI) != null){
515515
vrBinding = settings.getInteger(VRConstants.SETTING_VRAPI);
516+
}else{
517+
vrBinding = VRConstants.SETTING_VRAPI_OPENVR_LWJGL_VALUE; //this is the binding that is best supported so makes sense to be the default
516518
}
517519

518520
if (settings.get(VRConstants.SETTING_SEATED_EXPERIENCE) != null){
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.jme3.input.vr;
2+
3+
public class AnalogActionState{
4+
5+
/**
6+
* The X coordinate of the analog data (typically between -1 and 1 for joystick coordinates or 0 and 1 for
7+
* trigger pulls)
8+
*/
9+
public final float x;
10+
11+
/**
12+
* The Y coordinate of the analog data (typically between -1 and 1)
13+
*
14+
* Will be zero if the analog action doesn't have at least 2 dimensions
15+
*/
16+
public final float y;
17+
18+
/**
19+
* The Z coordinate of the analog data (typically between -1 and 1)
20+
*
21+
* Will be zero if the analog action doesn't have at least 3 dimensions
22+
*/
23+
public final float z;
24+
25+
/**
26+
* The change in the X coordinate since the last frame
27+
*/
28+
public final float deltaX;
29+
30+
/**
31+
* The change in the Y coordinate since the last frame
32+
*/
33+
public final float deltaY;
34+
35+
/**
36+
* The change in the Z coordinate since the last frame
37+
*/
38+
public final float deltaZ;
39+
40+
public AnalogActionState(float x, float y, float z, float deltaX, float deltaY, float deltaZ){
41+
this.x = x;
42+
this.y = y;
43+
this.z = z;
44+
this.deltaX = deltaX;
45+
this.deltaY = deltaY;
46+
this.deltaZ = deltaZ;
47+
}
48+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.jme3.input.vr;
2+
3+
public class DigitalActionState{
4+
5+
/**
6+
* The current value of this action
7+
*/
8+
public final boolean state;
9+
10+
/**
11+
* If since the last loop the value of this action has changed
12+
*/
13+
public final boolean changed;
14+
15+
public DigitalActionState(boolean state, boolean changed){
16+
this.state = state;
17+
this.changed = changed;
18+
}
19+
}

jme3-vr/src/main/java/com/jme3/input/vr/VRInputAPI.java

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,178 @@
44
import com.jme3.math.Vector2f;
55
import com.jme3.math.Vector3f;
66

7+
import java.util.Collection;
8+
79
/**
810
* An interface that represents a VR input (typically a VR device such as a controller).
911
* @author reden - phr00t - https://github.com/phr00t
1012
* @author Julien Seinturier - COMEX SA - <a href="http://www.seinturier.fr">http://www.seinturier.fr</a>
1113
*/
1214
public interface VRInputAPI {
15+
16+
/**
17+
* Registers an action manifest. An actions manifest is a file that defines "actions" a player can make.
18+
* (An action is an abstract version of a button press). The action manifest may then also include references to
19+
* further files that define default mappings between those actions and physical buttons on the VR controllers.
20+
*
21+
* Note that registering an actions manifest will deactivate legacy inputs (i.e. methods such as {@link #isButtonDown}
22+
* will no longer work
23+
*
24+
* This option is only relevant to OpenVR
25+
* @param actionManifestAbsolutePath
26+
* the absolute file path to an actions manifest
27+
* @param startingActiveActionSet
28+
* the actions in the manifest are divided into action sets (groups) by their prefix (e.g. "/actions/main").
29+
* These action sets can be turned off and on per frame. This argument sets the action set that will be
30+
* active now. The active action sets can be later be changed by calling {@link #setActiveActionSet}.
31+
* Note that at present only a single set at a time is supported
32+
*
33+
*/
34+
default void registerActionManifest( String actionManifestAbsolutePath, String startingActiveActionSet ){
35+
throw new UnsupportedOperationException("Action manifests are not supported for the currently used VR API");
36+
}
37+
38+
/**
39+
* Updates the active action set (the action group that will have their states available to be polled).
40+
*
41+
* Note that this update will not take effect until the next loop
42+
* Note that at present only a single set at a time is supported
43+
*
44+
* @param activeActionSet
45+
* the actions in the manifest are divided into action sets (groups) by their prefix (e.g. "/actions/main").
46+
* These action sets can be turned off and on per frame. This argument sets the action set that will be
47+
* active now.
48+
*/
49+
default void setActiveActionSet( String activeActionSet ){
50+
throw new UnsupportedOperationException("Action manifests are not supported for the currently used VR API");
51+
}
52+
53+
/**
54+
* Gets the current state of the action (abstract version of a button press).
55+
*
56+
* This is called for digital style actions (a button is pressed, or not)
57+
*
58+
* This method is commonly called when it's not important which hand the action is bound to (e.g. if a button press
59+
* is opening your inventory that could be bound to either left or right hand and that would not matter).
60+
*
61+
* If the handedness matters use {@link #getDigitalActionState(String, String)}
62+
*
63+
* {@link #registerActionManifest} must have been called before using this method.
64+
*
65+
* @param actionName The name of the action. Will be something like /actions/main/in/openInventory
66+
* @return the DigitalActionState that has details on if the state has changed, what the state is etc.
67+
*/
68+
default DigitalActionState getDigitalActionState( String actionName ){
69+
return getDigitalActionState(actionName, null);
70+
}
71+
72+
/**
73+
* Gets the current state of the action (abstract version of a button press).
74+
*
75+
* This is called for digital style actions (a button is pressed, or not)
76+
*
77+
* This method is commonly called when it is important which hand the action is found on. For example while
78+
* holding a weapon a button may be bound to "eject magazine" to allow you to load a new one, but that would only
79+
* want to take effect on the hand that is holding the weapon
80+
*
81+
* Note that restrictToInput only restricts, it must still be bound to the input you want to receive the input from in
82+
* the action manifest default bindings.
83+
*
84+
* {@link #registerActionManifest} must have been called before using this method.
85+
*
86+
* @param actionName The name of the action. E.g. /actions/main/in/openInventory
87+
* @param restrictToInput the input to restrict the action to. E.g. /user/hand/right. Or null, which means "any input"
88+
* @return the DigitalActionState that has details on if the state has changed, what the state is etc.
89+
*/
90+
default DigitalActionState getDigitalActionState( String actionName, String restrictToInput ){
91+
throw new UnsupportedOperationException("Action manifests are not supported for the currently used VR API");
92+
}
93+
94+
/**
95+
* Gets the current state of the action (abstract version of a button press).
96+
*
97+
* This is called for analog style actions (most commonly joysticks, but button pressure can also be mapped in analog).
98+
*
99+
* This method is commonly called when it's not important which hand the action is bound to (e.g. if the thumb stick
100+
* is controlling a third-person character in-game that could be bound to either left or right hand and that would
101+
* not matter).
102+
*
103+
* If the handedness matters use {@link #getAnalogActionState(String, String)}
104+
*
105+
* {@link #registerActionManifest} must have been called before using this method.
106+
*
107+
* @param actionName The name of the action. E.g. /actions/main/in/openInventory
108+
* @return the DigitalActionState that has details on if the state has changed, what the state is etc.
109+
*/
110+
default AnalogActionState getAnalogActionState( String actionName ){
111+
return getAnalogActionState(actionName, null);
112+
}
113+
114+
/**
115+
* Gets the current state of the action (abstract version of a button press).
116+
*
117+
* This is called for analog style actions (most commonly joysticks, but button pressure can also be mapped in analog).
118+
*
119+
* This method is commonly called when it is important which hand the action is found on. For example an "in universe"
120+
* joystick that has a hat control might (while you are holding it) bind to the on-controller hat, but only on the hand
121+
* holding it
122+
*
123+
* Note that restrictToInput only restricts, it must still be bound to the input you want to receive the input from in
124+
* the action manifest default bindings.
125+
*
126+
* {@link #registerActionManifest} must have been called before using this method.
127+
*
128+
* @param actionName The name of the action. E.g. /actions/main/in/openInventory
129+
* @param restrictToInput the input to restrict the action to. E.g. /user/hand/right. Or null, which means "any input"
130+
* @return the DigitalActionState that has details on if the state has changed, what the state is etc.
131+
*/
132+
default AnalogActionState getAnalogActionState( String actionName, String restrictToInput ){
133+
throw new UnsupportedOperationException("Action manifests are not supported for the currently used VR API");
134+
}
135+
13136
/**
14137
* Check if the given button is down (more generally if the given input type is activated).
138+
*
139+
* Deprecated as should use an actions manifest approach. See {@link #registerActionManifest}
140+
*
15141
* @param controllerIndex the index of the controller to check.
16142
* @param checkButton the button / input to check.
17143
* @return <code>true</code> if the button / input is down / activated and <code>false</code> otherwise.
18144
*/
145+
@Deprecated
19146
public boolean isButtonDown(int controllerIndex, VRInputType checkButton);
20147

21148
/**
22149
* Check if the given button / input from the given controller has been just pressed / activated.
150+
*
151+
* Deprecated as should use an actions manifest approach. See {@link #registerActionManifest}
152+
*
23153
* @param controllerIndex the index of the controller.
24154
* @param checkButton the button / input to check.
25155
* @return <code>true</code> if the given button / input from the given controller has been just pressed / activated and <code>false</code> otherwise.
26156
*/
157+
@Deprecated
27158
public boolean wasButtonPressedSinceLastCall(int controllerIndex, VRInputType checkButton);
28159

29160
/**
30161
* Reset the current activation of the inputs. After a call to this method, all input activation is considered as new activation.
31162
* @see #wasButtonPressedSinceLastCall(int, VRInputType)
163+
*
164+
* Deprecated as should use an actions manifest approach. See {@link #registerActionManifest}
32165
*/
166+
@Deprecated
33167
public void resetInputSinceLastCall();
34168

35169
/**
36170
* Get the controller axis delta from the last value.
171+
*
172+
* Deprecated as should use an actions manifest approach. See {@link #registerActionManifest}
173+
*
37174
* @param controllerIndex the index of the controller.
38175
* @param forAxis the axis.
39176
* @return the controller axis delta from the last call.
40177
*/
178+
@Deprecated
41179
public Vector2f getAxisDeltaSinceLastCall(int controllerIndex, VRInputType forAxis);
42180

43181
/**
@@ -59,21 +197,29 @@ public interface VRInputAPI {
59197
/**
60198
* Get the axis value for the given input on the given controller.
61199
* This value is the {@link #getAxisRaw(int, VRInputType) raw value} multiplied by the {@link #getAxisMultiplier() axis multiplier}.
200+
*
201+
* Deprecated as should use an actions manifest approach. See {@link #registerActionManifest}
202+
*
62203
* @param controllerIndex the index of the controller.
63204
* @param forAxis the axis.
64205
* @return the axis value for the given input on the given controller.
65206
* @see #getAxisRaw(int, VRInputType)
66207
* @see #getAxisMultiplier()
67208
*/
209+
@Deprecated
68210
public Vector2f getAxis(int controllerIndex, VRInputType forAxis);
69211

70212
/**
71213
* Get the axis value for the given input on the given controller.
214+
*
215+
* Deprecated as should use an actions manifest approach. See {@link #registerActionManifest}
216+
*
72217
* @param controllerIndex the index of the controller.
73218
* @param forAxis the axis.
74219
* @return the axis value for the given input on the given controller.
75220
* @see #getAxis(int, VRInputType)
76221
*/
222+
@Deprecated
77223
public Vector2f getAxisRaw(int controllerIndex, VRInputType forAxis);
78224

79225
/**
@@ -184,8 +330,46 @@ public interface VRInputAPI {
184330

185331
/**
186332
* Trigger a haptic pulse on the selected controller for the duration given in parameters (in seconds).
333+
*
334+
* Deprecated, use triggerHapticAction instead (as it has more options and doesn't use deprecated methods)
335+
*
187336
* @param controllerIndex the index of the controller.
188337
* @param seconds the duration of the pulse in seconds.
189338
*/
339+
@Deprecated
190340
public void triggerHapticPulse(int controllerIndex, float seconds);
341+
342+
/**
343+
* Triggers a haptic action (aka a vibration).
344+
*
345+
* Note if you want a haptic action in only one hand that is done either by only binding the action to one hand in
346+
* the action manifest's standard bindings or by binding to both and using {@link #triggerHapticAction(String, float, float, float, String)}
347+
* to control which input it gets set to at run time
348+
*
349+
* @param actionName The name of the action. Will be something like /actions/main/out/vibrate
350+
* @param duration how long in seconds the
351+
* @param frequency in cycles per second
352+
* @param amplitude between 0 and 1
353+
*/
354+
default void triggerHapticAction( String actionName, float duration, float frequency, float amplitude){
355+
triggerHapticAction( actionName, duration, frequency, amplitude, null );
356+
}
357+
358+
/**
359+
* Triggers a haptic action (aka a vibration) restricted to just one input (e.g. left or right hand).
360+
*
361+
* Note that restrictToInput only restricts, it must still be bound to the input you want to send the haptic to in
362+
* the action manifest default bindings.
363+
*
364+
* This method is typically used to bind the haptic to both hands then decide at run time which hand to sent to *
365+
*
366+
* @param actionName The name of the action. Will be something like /actions/main/out/vibrate
367+
* @param duration how long in seconds the
368+
* @param frequency in cycles per second
369+
* @param amplitude between 0 and 1
370+
* @param restrictToInput the input to restrict the action to. E.g. /user/hand/right. Or null, which means "any input"
371+
*/
372+
default void triggerHapticAction( String actionName, float duration, float frequency, float amplitude, String restrictToInput){
373+
throw new UnsupportedOperationException("Action manifests are not supported for the currently used VR API");
374+
}
191375
}

jme3-vr/src/main/java/com/jme3/input/vr/VRInputType.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
* @author reden - phr00t - https://github.com/phr00t
66
* @author Julien Seinturier - COMEX SA - <a href="http://www.seinturier.fr">http://www.seinturier.fr</a>
77
*
8+
* Deprecated, use the LWJGL openVR bindings and use actions instead
9+
*
810
*/
11+
@Deprecated
912
public enum VRInputType {
1013
/**
1114
* an HTC vive trigger axis (about <a href="https://www.vive.com/us/support/category_howto/720435.html">Vive controller</a>).

0 commit comments

Comments
 (0)