mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +02:00
Fix reticle transform when depth != 1
This commit is contained in:
parent
28103cf5ef
commit
f5acf49e47
3 changed files with 24 additions and 37 deletions
|
@ -26,7 +26,6 @@
|
|||
|
||||
// Used to animate the magnification windows
|
||||
|
||||
static const quint64 MSECS_TO_USECS = 1000ULL;
|
||||
//static const quint64 TOOLTIP_DELAY = 500 * MSECS_TO_USECS;
|
||||
|
||||
static const float reticleSize = TWO_PI / 100.0f;
|
||||
|
@ -432,42 +431,31 @@ void CompositorHelper::toggle() {
|
|||
}
|
||||
|
||||
|
||||
glm::mat4 CompositorHelper::getReticleTransform(const glm::mat4& eyePose, const glm::mat4& headPose) const {
|
||||
|
||||
glm::mat4 CompositorHelper::getReticleTransform(const glm::mat4& eyePose, const glm::vec3& headPosition) const {
|
||||
glm::mat4 result;
|
||||
if (isHMD()) {
|
||||
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
|
||||
auto reticlePosition = getReticlePosition();
|
||||
if (getReticleDepth() != 1.0f) {
|
||||
auto spherical = overlayToSpherical(reticlePosition);
|
||||
auto sphereSurfacePoint = getPoint(spherical.x, spherical.y);
|
||||
auto origin = vec3(headPose[3]);
|
||||
auto direction = glm::normalize(sphereSurfacePoint - origin);
|
||||
auto apparentPosition = (direction * getReticleDepth());
|
||||
|
||||
// same code as used to render for apparent location
|
||||
auto relativePosition4 = glm::inverse(eyePose) * vec4(apparentPosition, 1);
|
||||
auto relativePosition = vec3(relativePosition4) / relativePosition4.w;
|
||||
auto relativeDistance = glm::length(relativePosition);
|
||||
|
||||
// look at borrowed from overlays
|
||||
float elevation = -asinf(relativePosition.y / glm::length(relativePosition));
|
||||
float azimuth = atan2f(relativePosition.x, relativePosition.z);
|
||||
glm::quat faceCamera = glm::quat(glm::vec3(elevation, azimuth, 0)) * quat(vec3(0, -PI, 0)); // this extra *quat(vec3(0,-PI,0)) was required to get the quad to flip this seems like we could optimize
|
||||
|
||||
Transform transform;
|
||||
transform.setTranslation(relativePosition);
|
||||
transform.setScale(reticleScale);
|
||||
transform.postScale(relativeDistance);
|
||||
transform.setRotation(faceCamera);
|
||||
transform.getMatrix(result);
|
||||
} else {
|
||||
glm::mat4 overlayXfm;
|
||||
_modelTransform.getMatrix(overlayXfm);
|
||||
glm::vec2 projection = overlayToSpherical(reticlePosition);
|
||||
mat4 pointerXfm = glm::inverse(eyePose) * glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
||||
mat4 reticleXfm = overlayXfm * pointerXfm;
|
||||
result = glm::scale(reticleXfm, reticleScale);
|
||||
}
|
||||
auto spherical = overlayToSpherical(reticlePosition);
|
||||
// The pointer transform relative to the sensor
|
||||
auto pointerTransform = glm::mat4_cast(quat(vec3(-spherical.y, spherical.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
||||
float reticleDepth = getReticleDepth();
|
||||
if (reticleDepth != 1.0f) {
|
||||
// Cursor position in UI space
|
||||
auto cursorPosition = vec3(pointerTransform[3]) / pointerTransform[3].w;
|
||||
// Ray to the cursor, in UI space
|
||||
auto cursorRay = glm::normalize(cursorPosition - headPosition) * reticleDepth;
|
||||
// Move the ray to be relative to the head pose
|
||||
pointerTransform[3] = vec4(cursorRay + headPosition, 1);
|
||||
// Scale up the cursor because of distance
|
||||
reticleScale *= reticleDepth;
|
||||
}
|
||||
glm::mat4 overlayXfm;
|
||||
_modelTransform.getMatrix(overlayXfm);
|
||||
pointerTransform = overlayXfm * pointerTransform;
|
||||
pointerTransform = glm::inverse(eyePose) * pointerTransform;
|
||||
result = glm::scale(pointerTransform, reticleScale);
|
||||
} else {
|
||||
static const float CURSOR_PIXEL_SIZE = 32.0f;
|
||||
static auto renderingWidget = PluginContainer::getInstance().getPrimaryWidget();
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
|
||||
glm::vec2 getReticleMaximumPosition() const;
|
||||
|
||||
glm::mat4 getReticleTransform(const glm::mat4& eyePose = glm::mat4(), const glm::mat4& headPose = glm::mat4()) const;
|
||||
glm::mat4 getReticleTransform(const glm::mat4& eyePose = glm::mat4(), const glm::vec3& headPosition = glm::vec3()) const;
|
||||
|
||||
ReticleInterface* getReticleInterface() { return _reticleInterface; }
|
||||
|
||||
|
|
|
@ -77,12 +77,11 @@ void HmdDisplayPlugin::compositePointer() {
|
|||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
_plane->Use();
|
||||
// Reconstruct the headpose from the eye poses
|
||||
auto currentHeadPose = _currentRenderEyePoses[Left];
|
||||
currentHeadPose[3] = vec4((vec3(_currentRenderEyePoses[Left][3]) + vec3(_currentRenderEyePoses[Right][3])) / 2.0f, 1.0f);
|
||||
auto headPosition = (vec3(_currentRenderEyePoses[Left][3]) + vec3(_currentRenderEyePoses[Right][3])) / 2.0f;
|
||||
for_each_eye([&](Eye eye) {
|
||||
using namespace oglplus;
|
||||
eyeViewport(eye);
|
||||
auto reticleTransform = compositorHelper->getReticleTransform(_currentRenderEyePoses[eye], currentHeadPose);
|
||||
auto reticleTransform = compositorHelper->getReticleTransform(_currentRenderEyePoses[eye], headPosition);
|
||||
Uniform<glm::mat4>(*_program, _modelViewUniform).Set(reticleTransform);
|
||||
Uniform<glm::mat4>(*_program, _projectionUniform).Set(_eyeProjections[eye]);
|
||||
_plane->Draw();
|
||||
|
|
Loading…
Reference in a new issue