make web overlays match web entities more, remove resolution

This commit is contained in:
SamGondelman 2017-11-09 17:09:45 -08:00
parent 9188ae9fb5
commit e38b0ab6b8
5 changed files with 61 additions and 77 deletions

View file

@ -56,14 +56,15 @@
#include "ui/Snapshot.h"
#include "SoundCache.h"
static const float DPI = 30.47f;
static int MAX_WINDOW_SIZE = 4096;
static const float INCHES_TO_METERS = 1.0f / 39.3701f;
static const float METERS_TO_INCHES = 39.3701f;
static const float OPAQUE_ALPHA_THRESHOLD = 0.99f;
const QString Web3DOverlay::TYPE = "web3d";
const QString Web3DOverlay::QML = "Web3DOverlay.qml";
Web3DOverlay::Web3DOverlay() : _dpi(DPI) {
Web3DOverlay::Web3DOverlay() {
_touchDevice.setCapabilities(QTouchDevice::Position);
_touchDevice.setType(QTouchDevice::TouchScreen);
_touchDevice.setName("RenderableWebEntityItemTouchDevice");
@ -80,7 +81,6 @@ Web3DOverlay::Web3DOverlay(const Web3DOverlay* Web3DOverlay) :
_url(Web3DOverlay->_url),
_scriptURL(Web3DOverlay->_scriptURL),
_dpi(Web3DOverlay->_dpi),
_resolution(Web3DOverlay->_resolution),
_showKeyboardFocusHighlight(Web3DOverlay->_showKeyboardFocusHighlight)
{
_geometryId = DependencyManager::get<GeometryCache>()->allocateID();
@ -152,7 +152,7 @@ void Web3DOverlay::buildWebSurface() {
setupQmlSurface();
}
_webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition()));
_webSurface->resize(QSize(_resolution.x, _resolution.y));
onResizeWebSurface();
_webSurface->resume();
});
@ -249,8 +249,16 @@ void Web3DOverlay::setMaxFPS(uint8_t maxFPS) {
}
void Web3DOverlay::onResizeWebSurface() {
_mayNeedResize = false;
_webSurface->resize(QSize(_resolution.x, _resolution.y));
glm::vec2 dims = glm::vec2(getDimensions());
dims *= METERS_TO_INCHES * _dpi;
// ensure no side is never larger then MAX_WINDOW_SIZE
float max = (dims.x > dims.y) ? dims.x : dims.y;
if (max > MAX_WINDOW_SIZE) {
dims *= MAX_WINDOW_SIZE / max;
}
_webSurface->resize(QSize(dims.x, dims.y));
}
const int INVALID_DEVICE_ID = -1;
@ -277,14 +285,14 @@ void Web3DOverlay::render(RenderArgs* args) {
return;
}
if (_currentMaxFPS != _desiredMaxFPS) {
setMaxFPS(_desiredMaxFPS);
}
if (_mayNeedResize) {
emit resizeWebSurface();
}
if (_currentMaxFPS != _desiredMaxFPS) {
setMaxFPS(_desiredMaxFPS);
}
vec4 color(toGlm(getColor()), getAlpha());
if (!_texture) {
@ -321,7 +329,7 @@ void Web3DOverlay::render(RenderArgs* args) {
Transform Web3DOverlay::evalRenderTransform() {
Transform transform = Parent::evalRenderTransform();
transform.setScale(1.0f);
transform.postScale(glm::vec3(getSize(), 1.0f));
transform.postScale(glm::vec3(getDimensions(), 1.0f));
return transform;
}
@ -520,18 +528,10 @@ void Web3DOverlay::setProperties(const QVariantMap& properties) {
}
}
auto resolution = properties["resolution"];
if (resolution.isValid()) {
bool valid;
auto res = vec2FromVariant(resolution, valid);
if (valid) {
_resolution = res;
}
}
auto dpi = properties["dpi"];
if (dpi.isValid()) {
_dpi = dpi.toFloat();
_mayNeedResize = true;
}
auto maxFPS = properties["maxFPS"];
@ -553,8 +553,6 @@ void Web3DOverlay::setProperties(const QVariantMap& properties) {
_inputMode = Touch;
}
}
_mayNeedResize = true;
}
QVariant Web3DOverlay::getProperty(const QString& property) {
@ -564,9 +562,6 @@ QVariant Web3DOverlay::getProperty(const QString& property) {
if (property == "scriptURL") {
return _scriptURL;
}
if (property == "resolution") {
return vec2toVariant(_resolution);
}
if (property == "dpi") {
return _dpi;
}
@ -622,17 +617,18 @@ void Web3DOverlay::setScriptURL(const QString& scriptURL) {
}
}
glm::vec2 Web3DOverlay::getSize() const {
return _resolution / _dpi * INCHES_TO_METERS * getDimensions();
};
bool Web3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
// FIXME - face and surfaceNormal not being returned
glm::vec2 dimensions = getDimensions();
glm::quat rotation = getRotation();
glm::vec3 position = getPosition();
// Don't call applyTransformTo() or setTransform() here because this code runs too frequently.
// Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale.
return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), getSize(), distance);
if (findRayRectangleIntersection(origin, direction, rotation, position, dimensions, distance)) {
surfaceNormal = rotation * Vectors::UNIT_Z;
face = glm::dot(surfaceNormal, direction) > 0 ? MIN_Z_FACE : MAX_Z_FACE;
return true;
} else {
return false;
}
}
Web3DOverlay* Web3DOverlay::createClone() const {
@ -641,4 +637,4 @@ Web3DOverlay* Web3DOverlay::createClone() const {
void Web3DOverlay::emitScriptEvent(const QVariant& message) {
QMetaObject::invokeMethod(this, "scriptEventReceived", Q_ARG(QVariant, message));
}
}

View file

@ -51,8 +51,6 @@ public:
void setProperties(const QVariantMap& properties) override;
QVariant getProperty(const QString& property) override;
glm::vec2 getSize() const override;
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance,
BoxFace& face, glm::vec3& surfaceNormal) override;
@ -92,8 +90,7 @@ private:
gpu::TexturePointer _texture;
QString _url;
QString _scriptURL;
float _dpi;
vec2 _resolution{ 640, 480 };
float _dpi { 30 };
int _geometryId { 0 };
bool _showKeyboardFocusHighlight{ true };

View file

@ -118,15 +118,16 @@ WebTablet = function (url, width, dpi, hand, clientOnly, location, visible) {
Overlays.deleteOverlay(this.webOverlayID);
}
var WEB_ENTITY_Z_OFFSET = (tabletDepth / 2) * (1 / sensorScaleFactor);
var WEB_ENTITY_Y_OFFSET = 0.004 * (1 / sensorScaleFactor);
var WEB_ENTITY_Z_OFFSET = (tabletDepth / 2.0) / sensorScaleFactor;
var WEB_ENTITY_Y_OFFSET = 0.004;
var screenWidth = 0.82 * tabletWidth;
var screenHeight = 0.81 * tabletHeight;
this.webOverlayID = Overlays.addOverlay("web3d", {
name: "WebTablet Web",
url: url,
localPosition: { x: 0, y: WEB_ENTITY_Y_OFFSET, z: -WEB_ENTITY_Z_OFFSET },
localRotation: Quat.angleAxis(180, Y_AXIS),
resolution: this.getTabletTextureResolution(),
dimensions: {x: screenWidth, y: screenHeight, z: 0.1},
dpi: tabletDpi,
color: { red: 255, green: 255, blue: 255 },
alpha: 1.0,
@ -139,7 +140,7 @@ WebTablet = function (url, width, dpi, hand, clientOnly, location, visible) {
var HOME_BUTTON_Y_OFFSET = ((tabletHeight / 2) - (tabletHeight / 20)) * (1 / sensorScaleFactor);
this.homeButtonID = Overlays.addOverlay("sphere", {
name: "homeButton",
localPosition: {x: -0.001, y: -HOME_BUTTON_Y_OFFSET, z: 0.0},
localPosition: {x: 0.0, y: -HOME_BUTTON_Y_OFFSET, z: 0.0},
localRotation: {x: 0, y: 1, z: 0, w: 0},
dimensions: { x: 4 * tabletScaleFactor, y: 4 * tabletScaleFactor, z: 4 * tabletScaleFactor},
alpha: 0.0,
@ -266,11 +267,16 @@ WebTablet.prototype.setLandscape = function(newLandscapeValue) {
this.landscape = newLandscapeValue;
Overlays.editOverlay(this.tabletEntityID,
{ rotation: this.landscape ? Quat.multiply(Camera.orientation, ROT_LANDSCAPE) :
Quat.multiply(Camera.orientation, ROT_Y_180) });
{ rotation: Quat.multiply(Camera.orientation, this.landscape ? ROT_LANDSCAPE : ROT_Y_180) });
var tabletWidth = getTabletWidthFromSettings() * MyAvatar.sensorToWorldScale;
var tabletScaleFactor = tabletWidth / TABLET_NATURAL_DIMENSIONS.x;
var tabletHeight = TABLET_NATURAL_DIMENSIONS.y * tabletScaleFactor;
var screenWidth = 0.82 * tabletWidth;
var screenHeight = 0.81 * tabletHeight;
Overlays.editOverlay(this.webOverlayID, {
resolution: this.getTabletTextureResolution(),
rotation: Quat.multiply(Camera.orientation, ROT_LANDSCAPE_WINDOW)
rotation: Quat.multiply(Camera.orientation, ROT_LANDSCAPE_WINDOW),
dimensions: {x: this.landscape ? screenHeight : screenWidth, y: this.landscape ? screenWidth : screenHeight, z: 0.1}
});
};

View file

@ -169,31 +169,13 @@ function calculateTouchTargetFromOverlay(touchTip, overlayID) {
// calclulate normalized position
var invRot = Quat.inverse(overlayRotation);
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, overlayPosition));
var dpi = Overlays.getProperty(overlayID, "dpi");
var dimensions;
if (dpi) {
// Calculate physical dimensions for web3d overlay from resolution and dpi; "dimensions" property
// is used as a scale.
var resolution = Overlays.getProperty(overlayID, "resolution");
if (resolution === undefined) {
return;
}
resolution.z = 1; // Circumvent divide-by-zero.
var scale = Overlays.getProperty(overlayID, "dimensions");
if (scale === undefined) {
return;
}
scale.z = 0.01; // overlay dimensions are 2D, not 3D.
dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale);
} else {
dimensions = Overlays.getProperty(overlayID, "dimensions");
if (dimensions === undefined) {
return;
}
if (!dimensions.z) {
dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D.
}
var dimensions = Overlays.getProperty(overlayID, "dimensions");
if (dimensions === undefined) {
return;
}
if (!dimensions.z) {
dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D.
}
var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z };
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT);

View file

@ -185,7 +185,7 @@ logTrace = function(str) {
// (the vector that would move the point outside the sphere)
// otherwise returns false
findSphereHit = function(point, sphereRadius) {
var EPSILON = 0.000001; //smallish positive number - used as margin of error for some computations
var EPSILON = 0.000001; //smallish positive number - used as margin of error for some computations
var vectorLength = Vec3.length(point);
if (vectorLength < EPSILON) {
return true;
@ -400,22 +400,25 @@ resizeTablet = function (width, newParentJointIndex, sensorToWorldScaleOverride)
});
// update webOverlay
var WEB_ENTITY_Z_OFFSET = (tabletDepth / 2) * sensorScaleOffsetOverride;
var WEB_ENTITY_Y_OFFSET = 0.004 * sensorScaleOffsetOverride;
var WEB_ENTITY_Z_OFFSET = (tabletDepth / 2.0) * sensorScaleOffsetOverride;
var WEB_ENTITY_Y_OFFSET = 0.004 * sensorScaleFactor * sensorScaleOffsetOverride;
var screenWidth = 0.82 * tabletWidth;
var screenHeight = 0.81 * tabletHeight;
Overlays.editOverlay(HMD.tabletScreenID, {
localPosition: { x: 0, y: WEB_ENTITY_Y_OFFSET, z: -WEB_ENTITY_Z_OFFSET },
dimensions: {x: screenWidth, y: screenHeight, z: 0.1},
dpi: tabletDpi
});
// update homeButton
var HOME_BUTTON_Y_OFFSET = ((tabletHeight / 2) - (tabletHeight / 20)) * sensorScaleOffsetOverride;
Overlays.editOverlay(HMD.homeButtonID, {
localPosition: {x: -0.001, y: -HOME_BUTTON_Y_OFFSET, z: 0.0},
localPosition: {x: 0, y: -HOME_BUTTON_Y_OFFSET, z: 0 },
dimensions: { x: 4 * tabletScaleFactor, y: 4 * tabletScaleFactor, z: 4 * tabletScaleFactor}
});
Overlays.editOverlay(HMD.homeButtonHighlightID, {
localPosition: { x: 0, y: -HOME_BUTTON_Y_OFFSET + 0.003, z: -0.0158 },
localPosition: { x: 0, y: -HOME_BUTTON_Y_OFFSET + 0.003 * sensorScaleFactor * sensorScaleOffsetOverride, z: -0.0158 * sensorScaleFactor * sensorScaleOffsetOverride },
dimensions: { x: 4 * tabletScaleFactor, y: 4 * tabletScaleFactor, z: 4 * tabletScaleFactor },
outerRadius: 25 * tabletScaleFactor,
innerRadius: 20 * tabletScaleFactor