From 567e4a435a1b39bda2347d68e397d3aa3557a66c Mon Sep 17 00:00:00 2001 From: StellaArtois Date: Wed, 7 May 2014 22:40:56 +0100 Subject: [PATCH] Implement basic dynamic head prediction time value (auto mode) based on previous frame time. --- .public_rev | 2 +- .../net/minecraft/src/RandomMobs.java.patch | 74 +++++++++++++++++++ src/com/mtbs3d/minecrift/MCController.java | 2 +- src/com/mtbs3d/minecrift/MCHydra.java | 2 +- src/com/mtbs3d/minecrift/MCMouse.java | 2 +- src/com/mtbs3d/minecrift/MCOculus.java | 14 ++++ .../minecrift/NullCenterEyePosition.java | 2 +- src/com/mtbs3d/minecrift/VRRenderer.java | 36 ++++++--- src/com/mtbs3d/minecrift/api/IBasePlugin.java | 2 +- .../mtbs3d/minecrift/api/PluginManager.java | 4 +- .../gui/GuiHeadOrientationSettings.java | 11 +-- .../mtbs3d/minecrift/settings/VRSettings.java | 7 +- 12 files changed, 134 insertions(+), 24 deletions(-) create mode 100644 patches/net/minecraft/src/RandomMobs.java.patch diff --git a/.public_rev b/.public_rev index db037923..bae72528 100644 --- a/.public_rev +++ b/.public_rev @@ -1 +1 @@ -52b34b662d19aa17bdd355794d401fa67605ff85 +bcb746de04323c6f905307b1ca1bcb3738f3f1be diff --git a/patches/net/minecraft/src/RandomMobs.java.patch b/patches/net/minecraft/src/RandomMobs.java.patch new file mode 100644 index 00000000..e8a6d95a --- /dev/null +++ b/patches/net/minecraft/src/RandomMobs.java.patch @@ -0,0 +1,74 @@ +--- a/net/minecraft/src/RandomMobs.java ++++ b/net/minecraft/src/RandomMobs.java +@@ -99,7 +99,7 @@ + } + else + { +- ResourceLocation entity; ++ ResourceLocation name; + + try + { +@@ -110,45 +110,44 @@ + initialize(); + } + +- if (renderGlobal != null) ++ if (renderGlobal == null) + { +- Entity entity1 = renderGlobal.renderedEntity; +- ResourceLocation name1; ++ ResourceLocation entity1 = loc; ++ return entity1; ++ } + +- if (entity1 == null) +- { +- name1 = loc; +- return name1; +- } ++ Entity entity = renderGlobal.renderedEntity; + +- if (!(entity1 instanceof EntityLiving)) +- { +- name1 = loc; +- return name1; +- } ++ if (entity == null) ++ { ++ name = loc; ++ return name; ++ } + +- String name = loc.getResourcePath(); ++ if (entity instanceof EntityLiving) ++ { ++ String name1 = loc.getResourcePath(); + +- if (!name.startsWith("textures/entity/")) ++ if (!name1.startsWith("textures/entity/")) + { + ResourceLocation uuidLow1 = loc; + return uuidLow1; + } + +- long uuidLow = entity1.getUniqueID().getLeastSignificantBits(); ++ long uuidLow = entity.getUniqueID().getLeastSignificantBits(); + int id = (int)(uuidLow & 2147483647L); + ResourceLocation var6 = getTextureLocation(loc, id); + return var6; + } + +- entity = loc; ++ name = loc; + } + finally + { + working = false; + } + +- return entity; ++ return name; + } + } + diff --git a/src/com/mtbs3d/minecrift/MCController.java b/src/com/mtbs3d/minecrift/MCController.java index 7423a716..d5d4d759 100644 --- a/src/com/mtbs3d/minecrift/MCController.java +++ b/src/com/mtbs3d/minecrift/MCController.java @@ -323,7 +323,7 @@ public boolean isInitialized() { } @Override - public void poll() { + public void poll(float delta) { if(!loaded) loadBindings(); JoystickAim.selectedJoystickMode = aimTypes[mc.vrSettings.joystickAimType]; diff --git a/src/com/mtbs3d/minecrift/MCHydra.java b/src/com/mtbs3d/minecrift/MCHydra.java index 4149c016..39f17dcb 100644 --- a/src/com/mtbs3d/minecrift/MCHydra.java +++ b/src/com/mtbs3d/minecrift/MCHydra.java @@ -172,7 +172,7 @@ public boolean isInitialized() { } @Override - public void poll() + public void poll(float delta) { if (!isInitialized()) return; diff --git a/src/com/mtbs3d/minecrift/MCMouse.java b/src/com/mtbs3d/minecrift/MCMouse.java index 95b5e092..2e792a9f 100644 --- a/src/com/mtbs3d/minecrift/MCMouse.java +++ b/src/com/mtbs3d/minecrift/MCMouse.java @@ -61,7 +61,7 @@ public boolean isInitialized() { } @Override - public void poll() { + public void poll(float delta) { if(this.mc.currentScreen == null && Display.isActive()) { this.mc.mouseHelper.mouseXYChange(); diff --git a/src/com/mtbs3d/minecrift/MCOculus.java b/src/com/mtbs3d/minecrift/MCOculus.java index d65b1339..334e042b 100644 --- a/src/com/mtbs3d/minecrift/MCOculus.java +++ b/src/com/mtbs3d/minecrift/MCOculus.java @@ -162,6 +162,20 @@ private void processCalibration() } } + @Override + public void poll(float delta) + { + if (isInitialized()) + { + if (delta != 0f) + { + _setPredictionEnabled(delta, true); + } + poll(); + } + } + + @Override public float getHeadYawDegrees() { return getYawDegrees_LH(); diff --git a/src/com/mtbs3d/minecrift/NullCenterEyePosition.java b/src/com/mtbs3d/minecrift/NullCenterEyePosition.java index aa7006bb..cb6b1d0a 100644 --- a/src/com/mtbs3d/minecrift/NullCenterEyePosition.java +++ b/src/com/mtbs3d/minecrift/NullCenterEyePosition.java @@ -57,7 +57,7 @@ public boolean isInitialized() { } @Override - public void poll() { + public void poll(float delta) { } @Override diff --git a/src/com/mtbs3d/minecrift/VRRenderer.java b/src/com/mtbs3d/minecrift/VRRenderer.java index 27f49c51..33800f75 100644 --- a/src/com/mtbs3d/minecrift/VRRenderer.java +++ b/src/com/mtbs3d/minecrift/VRRenderer.java @@ -7,11 +7,8 @@ package com.mtbs3d.minecrift; import java.lang.reflect.Field; -import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; import com.mtbs3d.minecrift.api.PluginManager; import com.mtbs3d.minecrift.render.DistortionParams; @@ -21,7 +18,6 @@ import com.mtbs3d.minecrift.utils.Utils; import de.fruitfly.ovr.EyeRenderParams; import de.fruitfly.ovr.OculusRift; -import org.lwjgl.BufferUtils; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.*; @@ -95,6 +91,12 @@ public class VRRenderer extends EntityRenderer // Debug double start = System.currentTimeMillis(); + // Ghetto frame timing test + long startFrameTimeMicroSecs = 0; + long endFrameTimeNanoSecs = 0; + long frameTimeNanoSecs = 0; + long targetFrameTimeNanoSecs = 0; + /* * MC: the minecraft world rendering code, below * GUI: the guiFBO, with GUI rendered into it @@ -524,18 +526,27 @@ public void updateCamera( float renderPartialTicks, boolean displayActive ) this.mc.vrSettings.posTrackResetPosition = false; } - if (this.mc.gameSettings.ofSmoothFps) + // Get timing just before orient / position reading + startFrameTimeMicroSecs = System.nanoTime(); + + // Poll for position, orientation, setting prediction time + if (this.mc.vrSettings.useHeadTrackPrediction && this.mc.vrSettings.headTrackPredictionTimeSecs == 0) + { + float frameTimeSecs = ((float) frameTimeNanoSecs) / 1000000000f; // TODO: Take median over last n frames + //System.out.println("Frametime Secs: " + frameTimeSecs); + PluginManager.pollAll(frameTimeSecs); + } + else { - GL11.glFinish(); + PluginManager.pollAll(0.0f); } - PluginManager.pollAll(); if(JoystickAim.selectedJoystickMode != null) JoystickAim.selectedJoystickMode.update( renderPartialTicks ); float lookYawOffset = mc.lookaimController.getBodyYawDegrees(); - float lookPitchOffset = mc.lookaimController.getBodyPitchDegrees(); - + float lookPitchOffset = mc.lookaimController.getBodyPitchDegrees(); + if (mc.headTracker.isInitialized() && this.mc.vrSettings.useHeadTracking) { this.mc.mcProfiler.startSection("oculus"); @@ -1018,6 +1029,13 @@ else if (this.mc.vrSettings.useSupersample) doDistortionAndSuperSample(); checkLatencyTester(); + // Finish frame + GL11.glFinish(); + + // Get end frame timings + endFrameTimeNanoSecs = System.nanoTime(); + frameTimeNanoSecs = endFrameTimeNanoSecs - startFrameTimeMicroSecs; + mc.checkGLError("After render world and GUI"); } diff --git a/src/com/mtbs3d/minecrift/api/IBasePlugin.java b/src/com/mtbs3d/minecrift/api/IBasePlugin.java index a25621bd..60c5c645 100644 --- a/src/com/mtbs3d/minecrift/api/IBasePlugin.java +++ b/src/com/mtbs3d/minecrift/api/IBasePlugin.java @@ -34,7 +34,7 @@ public interface IBasePlugin { public boolean isInitialized(); - public void poll(); + public void poll(float delta); public void destroy(); diff --git a/src/com/mtbs3d/minecrift/api/PluginManager.java b/src/com/mtbs3d/minecrift/api/PluginManager.java index 2aa44184..a46ba1ba 100644 --- a/src/com/mtbs3d/minecrift/api/PluginManager.java +++ b/src/com/mtbs3d/minecrift/api/PluginManager.java @@ -155,12 +155,12 @@ public static void register( IBasePlugin that ) thePluginManager.allPlugins.add(that); } - public static void pollAll() + public static void pollAll(float delta) { for( IBasePlugin p : thePluginManager.allPlugins ) { if( p.isInitialized() ) - p.poll(); + p.poll(delta); } } diff --git a/src/com/mtbs3d/minecrift/gui/GuiHeadOrientationSettings.java b/src/com/mtbs3d/minecrift/gui/GuiHeadOrientationSettings.java index 1aee80df..03ec3b0b 100644 --- a/src/com/mtbs3d/minecrift/gui/GuiHeadOrientationSettings.java +++ b/src/com/mtbs3d/minecrift/gui/GuiHeadOrientationSettings.java @@ -77,7 +77,7 @@ public void initGui() } else if (var8 == EnumOptions.HEAD_TRACK_PREDICTION_TIME) { - minValue = 0.001f; + minValue = 0.000f; maxValue = 0.100f; increment = 0.001f; } @@ -124,7 +124,7 @@ else if (par1GuiButton.id == 201) if(this.mc.headTracker instanceof MCOculus) { this.mc.vrSettings.useHeadTrackPrediction = true; - this.mc.vrSettings.headTrackPredictionTimeSecs = 0.015f; + this.mc.vrSettings.headTrackPredictionTimeSecs = 0f; mc.headTracker.setPrediction(this.mc.vrSettings.headTrackPredictionTimeSecs, this.mc.vrSettings.useHeadTrackPrediction); } this.mc.vrSettings.setHeadTrackSensitivity(1.0f); @@ -187,7 +187,7 @@ protected String[] getTooltipLines(String displayString, int buttonId) "For the Oculus Rift, enable Prediction?", " OFF: Prediction disabled", " ON: Prediction enabled", - " Recommended value: ON" } ; + " Recommended value: ON to reduce latency" } ; case HEAD_TRACK_SENSITIVITY: return new String[] { "In-game camera orientation multiplied by this value.", @@ -198,8 +198,9 @@ protected String[] getTooltipLines(String displayString, int buttonId) return new String[] { "Number of seconds to predict motion. Higher values will", "enhance the perceived precision of slow movements, but ", - "cause issues with sudden movements", - " Recommended value: 0.015"}; + "cause issues with sudden movements. Auto attempts to", + "dynamically set the value based on previous frame time.", + " Recommended value: AUTO (set to 0)"}; default: return null; } diff --git a/src/com/mtbs3d/minecrift/settings/VRSettings.java b/src/com/mtbs3d/minecrift/settings/VRSettings.java index d5027124..9c45cae8 100644 --- a/src/com/mtbs3d/minecrift/settings/VRSettings.java +++ b/src/com/mtbs3d/minecrift/settings/VRSettings.java @@ -47,7 +47,7 @@ public class VRSettings { public boolean loadMumbleLib = true; public boolean useHeadTracking = true; public boolean useHeadTrackPrediction = true; - public float headTrackPredictionTimeSecs = 0.015f; + public float headTrackPredictionTimeSecs = 0f; protected float ipd = 0.0635F; // Use getIPD() protected float oculusProfileIpd = ipd; public String oculusProfileName; @@ -629,7 +629,10 @@ public String getKeyBinding( EnumOptions par1EnumOptions ) case IPD: return var4 + String.format("%.1fmm", new Object[] { Float.valueOf(getIPD() * 1000) }); case HEAD_TRACK_PREDICTION_TIME: - return var4 + String.format("%.0fms", new Object[] { Float.valueOf(this.headTrackPredictionTimeSecs * 1000) }); + if (headTrackPredictionTimeSecs == 0.0f) + return var4 + "Auto"; + else + return var4 + String.format("%.0fms", new Object[] { Float.valueOf(this.headTrackPredictionTimeSecs * 1000) }); case HUD_OPACITY: if( this.hudOpacity > 0.99) return var4 +" Opaque";