Spatial functions and snippets

From the CreationKit Wiki
Jump to navigation Jump to search

This pages aims to present a few useful snippets for working with spatial transformations and computations in Skyrim.


Rotation matrix[edit | edit source]

This code is useful if you want to compute the position that results from a translation from an origin, then a rotation around that origin. This is useful if, for example, you want to place something on an "orbit" around another object. It was created by Chesko.

;-----------\
;Description \ Author: Chesko
;----------------------------------------------------------------
;Rotates a point (akObject offset from the center of
;rotation (akOrigin) by the supplied degrees fAngleX, fAngleY,
;fAngleZ, and returns the new position of the point.

;-------------\
;Return Values \
;----------------------------------------------------------------
;               fNewPos[0]      =        The new X position of the point
;               fNewPos[1]      =        The new Y position of the point
;               fNewPos[2]      =        The new Z position of the point

;                        |  1                    0                0     |
;Rx(t) =                 |  0                   cos(t)         -sin(t)  |
;                        |  0                   sin(t)          cos(t)  |
;
;                        | cos(t)                0              sin(t)  |
;Ry(t) =                 |  0                    1                0     |
;                        |-sin(t)                0              cos(t)  |
;
;                        | cos(t)              -sin(t)            0     |
;Rz(t) =                 | sin(t)               cos(t)            0     |
;                        |  0                    0                1     |

;R * v = Rv, where R = rotation matrix, v = column vector of point [ x y z ], Rv = column vector of point after rotation
;Provided angles must follow Bethesda's conventions (CW Z angle for example).
float[] function GetPosXYZRotateAroundRef(ObjectReference akOrigin, ObjectReference akObject, float fAngleX, float fAngleY, float fAngleZ)
        fAngleX = -(fAngleX)
        fAngleY = -(fAngleY)
        fAngleZ = -(fAngleZ)

        float myOriginPosX = akOrigin.GetPositionX()
        float myOriginPosY = akOrigin.GetPositionY()
        float myOriginPosZ = akOrigin.GetPositionZ()

        float fInitialX = akObject.GetPositionX() - myOriginPosX
        float fInitialY = akObject.GetPositionY() - myOriginPosY
        float fInitialZ = akObject.GetPositionZ() - myOriginPosZ

        float fNewX
        float fNewY
        float fNewZ

        ;Objects in Skyrim are rotated in order of Z, Y, X, so we will do that here as well.

        ;Z-axis rotation matrix
        float fVectorX = fInitialX
        float fVectorY = fInitialY
        float fVectorZ = fInitialZ
        fNewX = (fVectorX * cos(fAngleZ)) + (fVectorY * sin(-fAngleZ)) + (fVectorZ * 0)
        fNewY = (fVectorX * sin(fAngleZ)) + (fVectorY * cos(fAngleZ)) + (fVectorZ * 0)
        fNewZ = (fVectorX * 0) + (fVectorY * 0) + (fVectorZ * 1)        

        ;Y-axis rotation matrix
        fVectorX = fNewX
        fVectorY = fNewY
        fVectorZ = fNewZ
        fNewX = (fVectorX * cos(fAngleY)) + (fVectorY * 0) + (fVectorZ * sin(fAngleY))
        fNewY = (fVectorX * 0) + (fVectorY * 1) + (fVectorZ * 0)
        fNewZ = (fVectorX * sin(-fAngleY)) + (fVectorY * 0) + (fVectorZ * cos(fAngleY))

        ;X-axis rotation matrix
        fVectorX = fNewX
        fVectorY = fNewY
        fVectorZ = fNewZ        
        fNewX = (fVectorX * 1) + (fVectorY * 0) + (fVectorZ * 0)
        fNewY = (fVectorX * 0) + (fVectorY * cos(fAngleX)) + (fVectorZ * sin(-fAngleX))
        fNewZ = (fVectorX * 0) + (fVectorY * sin(fAngleX)) + (fVectorZ * cos(fAngleX))

        ;Return result
        float[] fNewPos = new float[3]
        fNewPos[0] = fNewX + myOriginPosX
        fNewPos[1] = fNewY + myOriginPosY
        fNewPos[2] = fNewZ + myOriginPosZ
        return fNewPos
endFunction

You may have to modify it to suit your needs.

  • myOriginPosX/Y/Z define the origin, the point from which we translate from and around which we rotate.
  • fVectorX/Y/Z define the translation from the origin.
  • fAngleX/Y/Z define the angles for the rotation around the origin.

See also[edit | edit source]