diff --git a/matrices.yyp b/matrices.yyp index 5b5dc93..27c624e 100644 --- a/matrices.yyp +++ b/matrices.yyp @@ -21,6 +21,7 @@ {"id":{"name":"UggPlane","path":"scripts/UggPlane/UggPlane.yy",},"order":5,}, {"id":{"name":"MatrixString","path":"scripts/MatrixString/MatrixString.yy",},"order":11,}, {"id":{"name":"__UggPrebuildCylinder","path":"scripts/__UggPrebuildCylinder/__UggPrebuildCylinder.yy",},"order":3,}, + {"id":{"name":"ScreenspaceToWorldspace","path":"scripts/ScreenspaceToWorldspace/ScreenspaceToWorldspace.yy",},"order":4,}, {"id":{"name":"__UggPrebuildSphere","path":"scripts/__UggPrebuildSphere/__UggPrebuildSphere.yy",},"order":4,}, {"id":{"name":"MatrixTransformVertexExt","path":"scripts/MatrixTransformVertexExt/MatrixTransformVertexExt.yy",},"order":12,}, {"id":{"name":"MatrixTranslate","path":"scripts/MatrixTranslate/MatrixTranslate.yy",},"order":13,}, @@ -28,6 +29,7 @@ {"id":{"name":"UggTriangle","path":"scripts/UggTriangle/UggTriangle.yy",},"order":9,}, {"id":{"name":"__UggPrebuildAABB","path":"scripts/__UggPrebuildAABB/__UggPrebuildAABB.yy",},"order":2,}, {"id":{"name":"__shdUgg","path":"shaders/__shdUgg/__shdUgg.yy",},"order":0,}, + {"id":{"name":"MouseToWorldspace","path":"scripts/MouseToWorldspace/MouseToWorldspace.yy",},"order":5,}, {"id":{"name":"MatrixFlipX","path":"scripts/MatrixFlipX/MatrixFlipX.yy",},"order":3,}, {"id":{"name":"UggRay","path":"scripts/UggRay/UggRay.yy",},"order":7,}, {"id":{"name":"MatrixFlipY","path":"scripts/MatrixFlipY/MatrixFlipY.yy",},"order":4,}, diff --git a/scripts/MouseToWorldspace/MouseToWorldspace.gml b/scripts/MouseToWorldspace/MouseToWorldspace.gml new file mode 100644 index 0000000..0084d34 --- /dev/null +++ b/scripts/MouseToWorldspace/MouseToWorldspace.gml @@ -0,0 +1,13 @@ +/// Returns the point in worldspace on the far clipping plane that lies under the mouse +/// +/// @param [viewMatrix] View matrix to use. If not provided, the current view matrix will be used +/// @param [projectionMatrix] Projection matrix to use. If not provided, the current projection matrix will be used + +function MouseToWorldspace(_viewMatrix = matrix_get(matrix_view), _projectionMatrix = matrix_get(matrix_projection)) +{ + return ScreenspaceToWorldspace(window_mouse_get_x(), + window_get_height() - window_mouse_get_y(), //GM's coordinate system requires that we invert this axis + window_get_width(), + window_get_height(), + MatrixInverse(matrix_multiply(_viewMatrix, _projectionMatrix))); +} \ No newline at end of file diff --git a/scripts/MouseToWorldspace/MouseToWorldspace.yy b/scripts/MouseToWorldspace/MouseToWorldspace.yy new file mode 100644 index 0000000..8a0c931 --- /dev/null +++ b/scripts/MouseToWorldspace/MouseToWorldspace.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "MouseToWorldspace", + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "Matrices", + "path": "Matrices.yyp", + }, +} \ No newline at end of file diff --git a/scripts/ScreenspaceToWorldspace/ScreenspaceToWorldspace.gml b/scripts/ScreenspaceToWorldspace/ScreenspaceToWorldspace.gml new file mode 100644 index 0000000..32f6576 --- /dev/null +++ b/scripts/ScreenspaceToWorldspace/ScreenspaceToWorldspace.gml @@ -0,0 +1,35 @@ +/// Returns the point in worldspace on the far clipping plane that lies under the given screenspace coordinates +/// +/// @param x x-coordinate in screenspace +/// @param y y-coordinate in screenspace +/// @param [width] Width of the screenspace render target. If not provided, the width of th current render target (either a surface or the backbuffer) will be used +/// @param [height] Height of the screenspace render target. If not provided, the height of the current render target (either a surface or the backbuffer) will be used +/// @param [inverseViewProjectionMatrix] The inverse of the view*projection matrix. If not provided, the current view and projection matrix will be used + +function ScreenspaceToWorldspace(_x, _y, _width, _height, _inverseMatrix) +{ + if ((_width == undefined) || (_height == undefined)) + { + var _surface = surface_get_target(); + } + + if (_width == undefined) _width = (_surface < 0)? display_get_gui_width() : surface_get_width( _surface); + if (_height == undefined) _height = (_surface < 0)? display_get_gui_height() : surface_get_height(_surface); + + _x = -1 + 2*_x/_width; + _y = -1 + 2*_y/_height; + + if (_inverseMatrix == undefined) + { + _inverseMatrix = MatrixInverse(matrix_multiply(matrix_get(matrix_view), matrix_get(matrix_projection))); + } + + var _vector = MatrixTransformVertexExt(_inverseMatrix, _x, _y, 1.0, 1.0); + + var _inverseW = 1/_vector[3]; + _vector[@ 0] *= _inverseW; + _vector[@ 1] *= _inverseW; + _vector[@ 2] *= _inverseW; + + return _vector; +} \ No newline at end of file diff --git a/scripts/ScreenspaceToWorldspace/ScreenspaceToWorldspace.yy b/scripts/ScreenspaceToWorldspace/ScreenspaceToWorldspace.yy new file mode 100644 index 0000000..4c15425 --- /dev/null +++ b/scripts/ScreenspaceToWorldspace/ScreenspaceToWorldspace.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "ScreenspaceToWorldspace", + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "Matrices", + "path": "Matrices.yyp", + }, +} \ No newline at end of file