From c27904aa92583938ca18d94abd3d403ef27b532a Mon Sep 17 00:00:00 2001 From: "glassmancody.info" Date: Wed, 14 Jun 2023 11:47:11 -0700 Subject: [PATCH] lua - add world to viewport function to camera --- apps/openmw/mwlua/camerabindings.cpp | 17 +++++++++++++++++ apps/openmw/mwrender/camera.cpp | 1 + apps/openmw/mwrender/camera.hpp | 2 ++ files/lua_api/openmw/camera.lua | 6 ++++++ 4 files changed, 26 insertions(+) diff --git a/apps/openmw/mwlua/camerabindings.cpp b/apps/openmw/mwlua/camerabindings.cpp index 4d27ce317c..bd5c43d24c 100644 --- a/apps/openmw/mwlua/camerabindings.cpp +++ b/apps/openmw/mwlua/camerabindings.cpp @@ -106,6 +106,23 @@ namespace MWLua return invertedViewMatrix.preMult(osg::Vec3f(x, y, -1)) - camera->getPosition(); }; + api["worldToViewportVector"] = [camera](osg::Vec3f pos) { + double width = Settings::Manager::getInt("resolution x", "Video"); + double height = Settings::Manager::getInt("resolution y", "Video"); + + osg::Matrix windowMatrix + = osg::Matrix::translate(1.0, 1.0, 1.0) * osg::Matrix::scale(0.5 * width, 0.5 * height, 0.5); + osg::Vec3f vpCoords = pos * (camera->getViewMatrix() * camera->getProjectionMatrix() * windowMatrix); + + // Move 0,0 to top left to match viewportToWorldVector + vpCoords.y() = height - vpCoords.y(); + + // Set the z component to be distance from camera, in world space units + vpCoords.z() = (pos - camera->getPosition()).length(); + + return vpCoords; + }; + return LuaUtil::makeReadOnly(api); } diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index cbdf416364..fbe5c6b4c7 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -127,6 +127,7 @@ namespace MWRender } cam->setViewMatrixAsLookAt(pos, pos + forward, up); mViewMatrix = cam->getViewMatrix(); + mProjectionMatrix = cam->getProjectionMatrix(); } void Camera::update(float duration, bool paused) diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index 627697620e..c6500160fd 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -109,6 +109,7 @@ namespace MWRender void setCollisionType(int collisionType) { mCollisionType = collisionType; } const osg::Matrixf& getViewMatrix() const { return mViewMatrix; } + const osg::Matrixf& getProjectionMatrix() const { return mProjectionMatrix; } private: MWWorld::Ptr mTrackingPtr; @@ -138,6 +139,7 @@ namespace MWRender bool mLockPitch = false, mLockYaw = false; osg::Vec3d mPosition; osg::Matrixf mViewMatrix; + osg::Matrixf mProjectionMatrix; float mCameraDistance, mPreferredCameraDistance; diff --git a/files/lua_api/openmw/camera.lua b/files/lua_api/openmw/camera.lua index c0307249b9..abe66e2d8c 100644 --- a/files/lua_api/openmw/camera.lua +++ b/files/lua_api/openmw/camera.lua @@ -224,5 +224,11 @@ -- @param openmw.util#Vector2 normalizedScreenPos -- @return openmw.util#Vector3 +--- Get vector from the world to the viewport for the given point in world space. +-- (0, 0) is the top left corner of the screen. +-- The z component of the return value holds the distance from the camera to the position, in world space +-- @function [parent=#camera] worldToViewportVector +-- @param openmw.util#Vector3 worldPos +-- @return openmw.util#Vector3 return nil