Matrix3 transforming viewport


I’m trying to transform the world according to the mouse position, but this only works correctly when the center of the scene is located at the coordinate 0,0.
The idea is to try to reach the effect of looking trough a window where the mouse is your head; when the mouse moves to the right, the world needs to ‘rotate’ to the left.
Like this:

This piece of code works when the scene is centered at the 0,0 coordinate:

X = Mouse.Pos.X
 Y = Mouse.Pos.Y
Z = -2
 CurrentViewMatrix = viewport.getTM()
 CurrentViewMatrix.row2 = [X, Y, Z]
 viewport.setTm  CurrentViewMatrix

Is there some sort of in coordsys local for the matrix3? Or am i missing something?


Anyone? Any tips to point me in the right direction?


Hi Corne,
The effect you’re trying to get seems to be not much different from camera orbit based on the mouse position in screen space. I don’t know how to get it, but can give you some Math hints for MaxScript.

    I guess you at least need two points the Camera Position and Camera Target Position to orbit around. I will call "Camera" the viewport point of view, since even the Perspective viewport is nothing but a Camera view with gizmos hidden. 

        -- Getting "Camera" Position and View Direction
        p3CameraWorldPos = (inverse(getViewTM())).row4
        p3CameraWorldDir = -(inverse(getViewTM())).row3
    You must work in a single coordinate system, the World space. You shouldn't put together screen coordinates (in pixels) and view coordinates (in system units). Here some hints about space mapping:

        -- From Screen (Mouse) space to View space:
        p2MouseScreenPos = mouse.pos -- Get Mouse Screen Position in pixels
        p3MouseViewPos = mapScreenToView p2MouseScreenPos -fDistance
        -- Distance between Camera Position and a generic Point Helper position:
        fDistance = distance p3CameraWorldPos $Point01.position
        -- In non ortho mode, you can make use of the Focal distance too.
        -- Camera Focal Distance:
        fFocalDist = gw.getFocalDist()
    fDistance is the distance between the Camera Position and where you want to sample the point in space. In non ortho viewports imagine to have a ray beam starting from Camera directed to the scene. We can roughly say that each screen pixel color is the result of one ray intersecting one surface, or nothing. To define one point in World space from View space we need a distance to set its position along the ray. In ortho viewports, the rays are all parallel, and the camera position shifts on a plane, but the principle is the same.

Space Mapping:

     -- From View space to World space:
        p3MouseWorldPos = p3MouseViewPos * inverse(getViewTM())
        -- And back, from World space to View space: 
        p3MouseViewPos = p3MouseWorldPos * getViewTM()
    If you want to avoid defining a distance to map View space to World space, you can use a Grid Helper, oriented like the Viewport Transform Matrix. You can position the Helper where you like, maybe it can be easier to manage since it's a "real" object.

        -- To create a Grid Helper oriented like Viewport Camera
        oGrid = grid()
        oGrid.rotation = (getViewTM()).rotation
        oGrid.position = $Point01.position -- Position of a generic Point Helper
        activeGrid = oGrid -- To make the new grid active.
   -- To set back the World Construction Plane:
   activeGrid = undefined

Space mapping:

        -- From Screen (mouse) space to Grid space:
        p2MouseScreenPos = mouse.pos -- Get Mouse Screen Position in pixels
        p3MouseGridPos = gw.getPointOnCP p2MouseScreenPos
        -- From Grid space to World space:
        p3MouseWorldPos = gw.mapCPToWorld p3MouseGridPos
        -- or
        p3MouseWorldPos = p3MouseGridPos * oGrid.transform
        -- And back, from World space to Grid space:
        p3MouseGridPos = p3MouseWorldPos * inverse(oGrid.transform)
    As a general rule:

        -- Vector from Object Local Space to World space:
        p3WorldVector = p3LocalVector * object.transform
        -- Vector from World space to Object Local space:
        p3LocalVector = P3WorldVector * inverse(object.transform)
    Transforms can be applied to translation, rotation or scale only. In example a normal vector can be transformed from one space to another with above rules but to be sure it still is a normal vector (it's length equals 1) it must be normalized. Otherwise it can be transformed by rotation only:

        -- Normal from Object Local Space to World Space:
        p3WorldNormal = p3LocalNormal * object.transform.rotationPart as Matrix3
        -- Normal from World space to Object Local Space:
        p3LocalNormal = p3WorldNormal * inverse(object.transform.rotationPart as Matrix3)

You can find more help in the MaxScript Reference under:
- Accessing Active Viewport Info, Type, and Transforms
- Point3 Values
- Matrix3 Values
- Frequently Asked Questions -> Working With Vectors

    And in the handy MaxScript Math thread:

I know this is not the answer to your question. Anyway I hope it can help you. I’m not an expert at Math, Please correct any mistake.

    - Cheers


Just incase you are trying to do what is already there, have you seen the walk through mode?


Wow, thanks SyncViewS. I’m going to look into some of your tips. Thanks!

and PEN, that’s not what I mean. That just moves your position, but i want to change the perspective of the world. It’s hard to explain, but if you look closely at that youtube movie i posted i’m sure you’ll see my point:


That is cool


This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.