mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +02:00
commit
7a9620ef99
4 changed files with 122 additions and 26 deletions
103
examples/example/hmd/pickerTest.js
Normal file
103
examples/example/hmd/pickerTest.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
Script.include("../../libraries/utils.js");
|
||||
|
||||
|
||||
PickerTest = function() {
|
||||
// Switch every 5 seconds between normal IPD and 0 IPD (in seconds)
|
||||
this.UPDATE_INTERVAL = 10.0;
|
||||
this.lastUpdateInterval = 0;
|
||||
|
||||
this.ballId = Overlays.addOverlay("sphere", {
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
color: { red: 0, green: 255, blue: 0 },
|
||||
size: 0.1,
|
||||
solid: true,
|
||||
alpha: 1.0,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
this.ballId2 = Overlays.addOverlay("sphere", {
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
color: { red: 255, green: 0, blue: 0 },
|
||||
size: 0.05,
|
||||
solid: true,
|
||||
alpha: 1.0,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
var that = this;
|
||||
Script.scriptEnding.connect(function() {
|
||||
that.onCleanup();
|
||||
});
|
||||
|
||||
Script.update.connect(function(deltaTime) {
|
||||
that.lastUpdateInterval += deltaTime;
|
||||
if (that.lastUpdateInterval >= that.UPDATE_INTERVAL) {
|
||||
that.onUpdate(that.lastUpdateInterval);
|
||||
that.lastUpdateInterval = 0;
|
||||
}
|
||||
});
|
||||
|
||||
Controller.mousePressEvent.connect(function(event) {
|
||||
that.onMousePress(event);
|
||||
});
|
||||
|
||||
Controller.mouseMoveEvent.connect(function(event) {
|
||||
that.onMouseMove(event);
|
||||
});
|
||||
|
||||
Controller.mouseReleaseEvent.connect(function(event) {
|
||||
that.onMouseRelease(event);
|
||||
});
|
||||
};
|
||||
|
||||
PickerTest.prototype.onCleanup = function() {
|
||||
Overlays.deleteOverlay(this.ballId)
|
||||
Overlays.deleteOverlay(this.ballId2)
|
||||
}
|
||||
|
||||
PickerTest.prototype.updateOverlays = function() {
|
||||
var pickRay = Camera.computePickRay(this.x, this.y);
|
||||
var origin = pickRay.origin;
|
||||
var direction = pickRay.direction;
|
||||
var position = Vec3.sum(origin, direction)
|
||||
Overlays.editOverlay(this.ballId, {
|
||||
position: position
|
||||
});
|
||||
|
||||
Overlays.editOverlay(this.ballId2, {
|
||||
position: origin
|
||||
});
|
||||
}
|
||||
|
||||
PickerTest.prototype.onUpdate = function(deltaTime) {
|
||||
if (this.clicked) {
|
||||
this.updateOverlays();
|
||||
}
|
||||
}
|
||||
|
||||
PickerTest.prototype.onMousePress = function(event) {
|
||||
if (event.button !== "LEFT") {
|
||||
return
|
||||
}
|
||||
this.clicked = true;
|
||||
this.x = event.x;
|
||||
this.y = event.y;
|
||||
this.updateOverlays();
|
||||
}
|
||||
|
||||
PickerTest.prototype.onMouseRelease = function(event) {
|
||||
if (event.button !== "LEFT") {
|
||||
return
|
||||
}
|
||||
this.clicked = false;
|
||||
}
|
||||
|
||||
PickerTest.prototype.onMouseMove = function(event) {
|
||||
if (this.clicked) {
|
||||
this.x = event.x;
|
||||
this.y = event.y;
|
||||
this.updateOverlays();
|
||||
}
|
||||
}
|
||||
|
||||
var PickerTest = new PickerTest();
|
|
@ -3175,14 +3175,13 @@ int Application::getBoundaryLevelAdjust() const {
|
|||
}
|
||||
|
||||
PickRay Application::computePickRay(float x, float y) const {
|
||||
glm::vec2 size = getCanvasSize();
|
||||
x /= size.x;
|
||||
y /= size.y;
|
||||
vec2 pickPoint{ x, y };
|
||||
PickRay result;
|
||||
if (isHMDMode()) {
|
||||
getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
|
||||
getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction);
|
||||
} else {
|
||||
getViewFrustum()->computePickRay(x, y, result.origin, result.direction);
|
||||
pickPoint /= getCanvasSize();
|
||||
getViewFrustum()->computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -346,31 +346,28 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
|
|||
|
||||
|
||||
void ApplicationCompositor::computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const {
|
||||
cursorPos *= qApp->getCanvasSize();
|
||||
const glm::vec2 projection = screenToSpherical(cursorPos);
|
||||
const glm::vec2 projection = overlayToSpherical(cursorPos);
|
||||
// The overlay space orientation of the mouse coordinates
|
||||
const glm::quat orientation(glm::vec3(-projection.y, projection.x, 0.0f));
|
||||
// FIXME We now have the direction of the ray FROM THE DEFAULT HEAD POSE.
|
||||
// Now we need to account for the actual camera position relative to the overlay
|
||||
glm::vec3 overlaySpaceDirection = glm::normalize(orientation * IDENTITY_FRONT);
|
||||
const glm::quat cursorOrientation(glm::vec3(-projection.y, projection.x, 0.0f));
|
||||
|
||||
// The orientation and position of the HEAD, not the overlay
|
||||
glm::vec3 worldSpaceHeadPosition = qApp->getCamera()->getPosition();
|
||||
glm::quat worldSpaceOrientation = qApp->getCamera()->getOrientation();
|
||||
|
||||
// We need the RAW camera orientation and position, because this is what the overlay is
|
||||
// rendered relative to
|
||||
glm::vec3 overlayPosition = qApp->getCamera()->getPosition();
|
||||
glm::quat overlayOrientation = qApp->getCamera()->getRotation();
|
||||
auto headPose = qApp->getHMDSensorPose();
|
||||
auto headOrientation = glm::quat_cast(headPose);
|
||||
auto headTranslation = extractTranslation(headPose);
|
||||
|
||||
auto overlayOrientation = worldSpaceOrientation * glm::inverse(headOrientation);
|
||||
auto overlayPosition = worldSpaceHeadPosition - (overlayOrientation * headTranslation);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::StandingHMDSensorMode)) {
|
||||
overlayPosition = _modelTransform.getTranslation();
|
||||
overlayOrientation = _modelTransform.getRotation();
|
||||
}
|
||||
|
||||
// Intersection UI overlay space
|
||||
glm::vec3 worldSpaceDirection = overlayOrientation * overlaySpaceDirection;
|
||||
glm::vec3 worldSpaceIntersection = (glm::normalize(worldSpaceDirection) * _oculusUIRadius) + overlayPosition;
|
||||
glm::vec3 worldSpaceHeadPosition = (overlayOrientation * extractTranslation(qApp->getHMDSensorPose())) + overlayPosition;
|
||||
|
||||
// Intersection in world space
|
||||
glm::vec3 worldSpaceIntersection = ((overlayOrientation * (cursorOrientation * Vectors::FRONT)) * _oculusUIRadius) + overlayPosition;
|
||||
|
||||
origin = worldSpaceHeadPosition;
|
||||
direction = glm::normalize(worldSpaceIntersection - worldSpaceHeadPosition);
|
||||
}
|
||||
|
@ -682,7 +679,6 @@ glm::vec2 ApplicationCompositor::screenToSpherical(const glm::vec2& screenPos) {
|
|||
result.y = (screenPos.y / screenSize.y - 0.5f);
|
||||
result.x *= MOUSE_YAW_RANGE;
|
||||
result.y *= MOUSE_PITCH_RANGE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -701,13 +697,13 @@ glm::vec2 ApplicationCompositor::sphericalToOverlay(const glm::vec2& sphericalP
|
|||
result /= _textureFov;
|
||||
result.x /= _textureAspectRatio;
|
||||
result += 0.5f;
|
||||
result *= qApp->getCanvasSize();
|
||||
result *= qApp->getUiSize();
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::vec2 ApplicationCompositor::overlayToSpherical(const glm::vec2& overlayPos) const {
|
||||
glm::vec2 result = overlayPos;
|
||||
result /= qApp->getCanvasSize();
|
||||
result /= qApp->getUiSize();
|
||||
result -= 0.5f;
|
||||
result *= _textureFov;
|
||||
result.x *= _textureAspectRatio;
|
||||
|
|
|
@ -497,9 +497,7 @@ QPointF OffscreenQmlSurface::mapWindowToUi(const QPointF& sourcePosition, QObjec
|
|||
}
|
||||
|
||||
QPointF OffscreenQmlSurface::mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget) {
|
||||
QPointF transformedPos = _mouseTranslator(originalPoint);
|
||||
transformedPos = mapWindowToUi(transformedPos, originalWidget);
|
||||
return transformedPos;
|
||||
return _mouseTranslator(originalPoint);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue