Skip to content

Commit

Permalink
Add support for curved display (#930)
Browse files Browse the repository at this point in the history
* Implement cylindrical layers

* Add geometry fallback to cylinder

* Adapt resize mode for Cylinders

* Add curved display setting
  • Loading branch information
MortimerGoro committed Feb 4, 2019
1 parent 0afae0d commit 2aa5299
Show file tree
Hide file tree
Showing 35 changed files with 1,408 additions and 331 deletions.
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Expand Up @@ -20,6 +20,7 @@ add_library( # Sets the name of the library.

# Provides a relative path to your source file(s).
src/main/cpp/BrowserWorld.cpp
src/main/cpp/Cylinder.cpp
src/main/cpp/Controller.cpp
src/main/cpp/ControllerContainer.cpp
src/main/cpp/DeviceUtils.cpp
Expand Down
Expand Up @@ -185,6 +185,7 @@ protected void onCreate(Bundle savedInstanceState) {
queueRunnable(() -> createOffscreenDisplay());
final String tempPath = getCacheDir().getAbsolutePath();
queueRunnable(() -> setTemporaryFilePath(tempPath));
setCylinderDensity(SettingsStore.getInstance(this).getCylinderDensity());
initializeWorld();

// Setup the search engine
Expand Down Expand Up @@ -983,6 +984,10 @@ public void resetUIYaw() {
queueRunnable(this::resetUIYawNative);
}

public void setCylinderDensity(final float aDensity) {
queueRunnable(() -> setCylinderDensityNative(aDensity));
}

private native void addWidgetNative(int aHandle, WidgetPlacement aPlacement);
private native void updateWidgetNative(int aHandle, WidgetPlacement aPlacement);
private native void removeWidgetNative(int aHandle);
Expand All @@ -999,4 +1004,5 @@ public void resetUIYaw() {
private native void resetUIYawNative();
private native void setControllersVisibleNative(boolean aVisible);
private native void runCallbackNative(long aCallback);
private native void setCylinderDensityNative(float aDensity);
}
Expand Up @@ -55,6 +55,7 @@ SettingsStore getInstance(final @NonNull Context aContext) {
public final static float BROWSER_WORLD_HEIGHT_DEFAULT = 2.25f;
public final static int MSAA_DEFAULT_LEVEL = 1;
public final static boolean AUDIO_ENABLED = false;
public final static float CYLINDER_DENSITY_ENABLED_DEFAULT = 4680.0f;

// Enable telemetry by default (opt-out).
private final static boolean enableCrashReportingByDefault = false;
Expand Down Expand Up @@ -361,4 +362,13 @@ public void setVoiceSearchLanguage(String language) {
editor.commit();
}

public float getCylinderDensity() {
return mPrefs.getFloat(mContext.getString(R.string.settings_key_cylinder_density), 0);
}

public void setCylinderDensity(float aDensity) {
SharedPreferences.Editor editor = mPrefs.edit();
editor.putFloat(mContext.getString(R.string.settings_key_cylinder_density), aDensity);
editor.commit();
}
}
Expand Up @@ -191,6 +191,7 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) {
aPlacement.rotation = (float)Math.toRadians(WidgetPlacement.floatDimension(context, R.dimen.keyboard_world_rotation));
aPlacement.worldWidth = WidgetPlacement.floatDimension(context, R.dimen.keyboard_world_width);
aPlacement.visible = false;
aPlacement.cylinder = true;
}

public void setBrowserWidget(UIWidget aWidget) {
Expand Down
Expand Up @@ -357,6 +357,7 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) {
aPlacement.parentAnchorY = 0.0f;
aPlacement.translationY = -35;
aPlacement.opaque = false;
aPlacement.cylinder = true;
}

@Override
Expand Down
Expand Up @@ -26,6 +26,7 @@ public RootWidget(Context aContext, AttributeSet aAttrs, int aDefStyle) {
protected void initializeWidgetPlacement(WidgetPlacement aPlacement) {
aPlacement.width = 8;
aPlacement.height = 8;
aPlacement.cylinder = false;
}

private void initialize(Context aContext) {
Expand Down
Expand Up @@ -61,9 +61,9 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) {
aPlacement.width = WidgetPlacement.dpDimension(context, R.dimen.top_bar_width);
aPlacement.height = WidgetPlacement.dpDimension(context, R.dimen.top_bar_height);
aPlacement.worldWidth = WidgetPlacement.floatDimension(getContext(), R.dimen.window_world_width) * aPlacement.width/getWorldWidth();
aPlacement.translationY = WidgetPlacement.unitFromMeters(context, R.dimen.top_bar_world_y);
//aPlacement.translationY = WidgetPlacement.unitFromMeters(context, R.dimen.top_bar_world_y);
aPlacement.anchorX = 0.5f;
aPlacement.anchorY = 0.5f;
aPlacement.anchorY = 0.0f;
aPlacement.parentAnchorX = 0.5f;
aPlacement.parentAnchorY = 1.0f;
aPlacement.opaque = false;
Expand Down
Expand Up @@ -202,6 +202,7 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) {
aPlacement.rotationAxisX = 1.0f;
aPlacement.rotation = (float)Math.toRadians(-45);
aPlacement.opaque = false;
aPlacement.cylinder = false;
}

@Override
Expand Down
Expand Up @@ -39,6 +39,7 @@ public WidgetPlacement(Context aContext) {
public boolean showPointer = true;
public boolean firstDraw = false;
public boolean layer = true;
public boolean cylinder = true;

public WidgetPlacement clone() {
WidgetPlacement w = new WidgetPlacement();
Expand Down Expand Up @@ -67,6 +68,8 @@ public void copyFrom(WidgetPlacement w) {
this.opaque = w.opaque;
this.showPointer = w.showPointer;
this.firstDraw = w.firstDraw;
this.layer = w.layer;
this.cylinder = w.cylinder;
}

public int textureWidth() {
Expand Down
Expand Up @@ -92,6 +92,7 @@ protected void initializeWidgetPlacement(WidgetPlacement aPlacement) {
aPlacement.anchorX = 0.5f;
aPlacement.anchorY = 0.0f;
aPlacement.visible = true;
aPlacement.cylinder = true;
}

@Override
Expand Down
Expand Up @@ -8,6 +8,7 @@
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ScrollView;

import org.mozilla.vrbrowser.R;
Expand All @@ -19,6 +20,7 @@
import org.mozilla.vrbrowser.ui.views.settings.DoubleEditSetting;
import org.mozilla.vrbrowser.ui.views.settings.RadioGroupSetting;
import org.mozilla.vrbrowser.ui.views.settings.SingleEditSetting;
import org.mozilla.vrbrowser.ui.views.settings.SwitchSetting;
import org.mozilla.vrbrowser.ui.widgets.WidgetManagerDelegate;
import org.mozilla.vrbrowser.ui.widgets.dialogs.RestartDialogWidget;
import org.mozilla.vrbrowser.ui.widgets.UIWidget;
Expand All @@ -31,6 +33,7 @@ public class DisplayOptionsWidget extends UIWidget implements
private AudioEngine mAudio;
private UIButton mBackButton;

private SwitchSetting mCurvedDisplaySwitch;
private RadioGroupSetting mUaModeRadio;
private RadioGroupSetting mMSAARadio;

Expand Down Expand Up @@ -76,6 +79,13 @@ private void initialize(Context aContext) {
}
});

mCurvedDisplaySwitch = findViewById(R.id.curved_display_switch);
mCurvedDisplaySwitch.setChecked(SettingsStore.getInstance(getContext()).getCylinderDensity() > 0.0f);
mCurvedDisplaySwitch.setOnCheckedChangeListener((compoundButton, enabled, apply) -> {
SettingsStore.getInstance(getContext()).setCylinderDensity(enabled ? SettingsStore.CYLINDER_DENSITY_ENABLED_DEFAULT : 0.0f);
showRestartDialog();
});

int uaMode = SettingsStore.getInstance(getContext()).getUaMode();
mUaModeRadio = findViewById(R.id.ua_radio);
mUaModeRadio.setOnCheckedChangeListener(mUaModeListener);
Expand Down
63 changes: 50 additions & 13 deletions app/src/main/cpp/BrowserWorld.cpp
Expand Up @@ -18,6 +18,7 @@
#include "Pointer.h"
#include "Widget.h"
#include "WidgetPlacement.h"
#include "Cylinder.h"
#include "Quad.h"
#include "VRBrowser.h"
#include "VRVideo.h"
Expand Down Expand Up @@ -150,6 +151,7 @@ struct BrowserWorld::State {
DrawableListPtr drawList;
CameraPtr leftCamera;
CameraPtr rightCamera;
float cylinderDensity;
float nearClip;
float farClip;
JNIEnv* env;
Expand All @@ -167,7 +169,7 @@ struct BrowserWorld::State {
SplashAnimationPtr splashAnimation;
VRVideoPtr vrVideo;

State() : paused(true), glInitialized(false), modelsLoaded(false), env(nullptr), nearClip(0.1f),
State() : paused(true), glInitialized(false), modelsLoaded(false), env(nullptr), cylinderDensity(0.0f), nearClip(0.1f),
farClip(300.0f), activity(nullptr), windowsInitialized(false), exitImmersiveRequested(false), loaderDelay(0) {
context = RenderContext::Create();
create = context->GetRenderThreadCreationContext();
Expand Down Expand Up @@ -272,15 +274,18 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) {
WidgetPtr hitWidget;
float hitDistance = farClip;
vrb::Vector hitPoint;
vrb::Vector hitNormal;
for (const WidgetPtr& widget: widgets) {
vrb::Vector result;
vrb::Vector normal;
float distance = 0.0f;
bool isInWidget = false;
if (widget->TestControllerIntersection(start, direction, result, isInWidget, distance)) {
if (widget->TestControllerIntersection(start, direction, result, normal, isInWidget, distance)) {
if (isInWidget && (distance < hitDistance)) {
hitWidget = widget;
hitDistance = distance;
hitPoint = result;
hitNormal = normal;
}
}
}
Expand All @@ -294,8 +299,10 @@ BrowserWorld::State::UpdateControllers(bool& aRelayoutWidgets) {
controller.pointer->SetVisible(hitWidget.get() != nullptr);
controller.pointer->SetHitWidget(hitWidget);
if (hitWidget) {
vrb::Matrix translate = vrb::Matrix::Translation(vrb::Vector(hitPoint.x(), hitPoint.y(), 0.001f));
controller.pointer->SetTransform(hitWidget->GetTransform().PostMultiply(translate));
vrb::Matrix translation = vrb::Matrix::Translation(hitPoint);
vrb::Matrix localRotation = vrb::Matrix::Rotation(hitNormal);
vrb::Matrix reorient = device->GetReorientTransform();
controller.pointer->SetTransform(reorient.AfineInverse().PostMultiply(translation).PostMultiply(localRotation));
}
}

Expand Down Expand Up @@ -701,17 +708,24 @@ BrowserWorld::AddWidget(int32_t aHandle, const WidgetPlacementPtr& aPlacement) {
int32_t textureWidth = (int32_t)(ceilf(aPlacement->width * aPlacement->density));
int32_t textureHeight = (int32_t)(ceilf(aPlacement->height * aPlacement->density));

const float aspect = (float)textureWidth / (float)textureHeight;
const float worldHeight = worldWidth / aspect;

WidgetPtr widget;
VRLayerQuadPtr layer;
if (aPlacement->layer && m.device) {
layer = m.device->CreateLayerQuad(textureWidth, textureHeight,
VRLayerQuad::SurfaceType::AndroidSurface);
if (aPlacement->cylinder && m.cylinderDensity > 0 && m.device) {
VRLayerCylinderPtr layer = m.device->CreateLayerCylinder(textureWidth, textureHeight, VRLayerQuad::SurfaceType::AndroidSurface);
CylinderPtr cylinder = Cylinder::Create(m.create, layer);
widget = Widget::Create(m.context, aHandle, textureWidth, textureHeight, worldWidth, worldHeight, cylinder);
}

if (layer) {
widget = Widget::Create(m.context, aHandle, layer, worldWidth);
} else {
widget = Widget::Create(m.context, aHandle, textureWidth, textureHeight, worldWidth);
if (!widget) {
VRLayerQuadPtr layer;
if (aPlacement->layer && m.device) {
layer = m.device->CreateLayerQuad(textureWidth, textureHeight, VRLayerQuad::SurfaceType::AndroidSurface);
}

QuadPtr quad = Quad::Create(m.create, worldWidth, worldHeight, layer);
widget = Widget::Create(m.context, aHandle, textureWidth, textureHeight, quad);
}

if (aPlacement->opaque) {
Expand Down Expand Up @@ -741,6 +755,7 @@ BrowserWorld::UpdateWidget(int32_t aHandle, const WidgetPlacementPtr& aPlacement
}

widget->SetPlacement(aPlacement);
widget->SetCylinderDensity(m.cylinderDensity);
widget->ToggleWidget(aPlacement->visible);
widget->SetSurfaceTextureSize((int32_t)(ceilf(aPlacement->width * aPlacement->density)),
(int32_t)(ceilf(aPlacement->height * aPlacement->density)));
Expand Down Expand Up @@ -846,6 +861,9 @@ BrowserWorld::LayoutWidget(int32_t aHandle) {
}

transform.TranslateInPlace(translation);
if (!parent) {
translation = transform.GetTranslation();
}
widget->SetTransform(parent ? parent->GetTransform().PostMultiply(transform) : transform);
}

Expand Down Expand Up @@ -911,6 +929,14 @@ BrowserWorld::ResetUIYaw() {
m.device->SetReorientTransform(matrix);
}

void
BrowserWorld::SetCylinderDensity(const float aDensity) {
m.cylinderDensity = aDensity;
for (WidgetPtr& widget: m.widgets) {
widget->SetCylinderDensity(aDensity);
}
}

JNIEnv*
BrowserWorld::GetJNIEnv() const {
ASSERT_ON_RENDER_THREAD(nullptr);
Expand Down Expand Up @@ -1149,9 +1175,14 @@ BrowserWorld::DistanceToPlane(const vrb::NodePtr& aNode, const vrb::Vector& aPos
return -1.0f;
}
vrb::Vector result;
vrb::Vector normal;
bool inside = false;
float distance = -1.0f;
target->GetQuad()->TestIntersection(aPosition, aDirection, result, false, inside, distance);
if (target->GetQuad()) {
target->GetQuad()->TestIntersection(aPosition, aDirection, result, normal, false, inside, distance);
} else if (target->GetCylinder()) {
distance = target->GetCylinder()->DistanceToBackPlane(aPosition, aDirection);
}
if (pointer) {
distance-= 0.001f;
}
Expand Down Expand Up @@ -1260,6 +1291,12 @@ JNI_METHOD(void, resetUIYawNative)
crow::BrowserWorld::Instance().ResetUIYaw();
}

JNI_METHOD(void, setCylinderDensityNative)
(JNIEnv* aEnv, jobject, jfloat aDensity) {
crow::BrowserWorld::Instance().SetCylinderDensity(aDensity);
}


JNI_METHOD(void, runCallbackNative)
(JNIEnv* aEnv, jobject, jlong aCallback) {
if (aCallback) {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/BrowserWorld.h
Expand Up @@ -55,6 +55,7 @@ class BrowserWorld {
void HideVRVideo();
void SetControllersVisible(const bool aVisible);
void ResetUIYaw();
void SetCylinderDensity(const float aDensity);
JNIEnv* GetJNIEnv() const;
protected:
struct State;
Expand Down

0 comments on commit 2aa5299

Please sign in to comment.