Camera

Scripts

14 years
edited 8 years
Camera library to ease camera setup and control.

Code (jass) Select

library Camera initializer Init requires Math

globals
    private constant integer TypeUnit = 'dgui'
    private location GL4Cam = Location(0,0)
    private unit AtUnit = null
    private real DeltaZ = 0
endglobals

globals
    constant real WidthScreen = 0.544
    constant real HeightScreen = 0.302
    constant real AspectRatio = WidthScreen/HeightScreen
endglobals

private function Matrix4Perspective1 takes MATRIX4 Output, real fovy, real Aspect, real zn, real zf returns MATRIX4
    return Output.SetValues(2*zn/fovy,0,0,0,0,2*zn/Aspect,0,0,0,0,zf/(zf-zn),1,0,0,zn*zf/(zn-zf),0)
endfunction

private function Matrix4Perspective2 takes MATRIX4 Output, real n, real f, real r, real l, real t, real b returns MATRIX4
    return Output.SetValues(2*n/(r-l), 0, (r+l)/(r-l), 0, 0, 2*n/(t-b), (t+b)/(t-b), 0, 0, 0, -(f+n)/(f-n), -2*f*n/(f-n), 0, 0, -1, 0)
endfunction

private function Matrix4Look takes MATRIX4 Output, VECTOR3 PosCamera, VECTOR3 AxisX, VECTOR3 AxisY, VECTOR3 AxisZ returns MATRIX4
    return Output.SetValues(AxisX.x,AxisY.x,AxisZ.x,0,AxisX.y,AxisY.y,AxisZ.y,0,AxisX.z,AxisY.z,AxisZ.z,0,-Vec3Dot(AxisX, PosCamera),-Vec3Dot(AxisY, PosCamera),-Vec3Dot(AxisZ, PosCamera),1)
endfunction

struct CAMERA
    VECTOR3 Eye
    VECTOR3 At
    real Distance
    real Yaw
    real Pitch
    real Roll
    VECTOR3 AxisX
    VECTOR3 AxisY
    VECTOR3 AxisZ
    private MATRIX4 View
    private MATRIX4 Projection
    private boolean change
    integer CostumValue
   
    method Win2World takes real X, real Y, real Range returns VECTOR3
        local VECTOR3 Output = VECTOR3.create()
        set Output.x = .Eye.x+.AxisZ.x*Range+X*.AxisX.x*WidthScreen*Range+Y*.AxisY.x*HeightScreen*Range
        set Output.y = .Eye.y+.AxisZ.y*Range+X*.AxisX.y*WidthScreen*Range+Y*.AxisY.y*HeightScreen*Range
        set Output.z = .Eye.z+.AxisZ.z*Range+X*.AxisX.z*WidthScreen*Range+Y*.AxisY.z*HeightScreen*Range
        return Output
    endmethod

    method World2Win takes real X, real Y, real Z returns VECTOR3
        local VECTOR3 Pos = VECTOR3.New_1(X, Y, Z)
        local boolean b
        call Vec3Transform_2(Pos, Pos, .View)
        set b = Pos.z < 0
        call Vec3Transform_2(Pos, Pos, .Projection)
        if b then
            set Pos.z = -Pos.z
        endif
        return Pos
    endmethod
   
    private method UpdateDistanceYawPitch takes nothing returns nothing
        local real dx = .At.x-.Eye.x
        local real dy = .At.y-.Eye.y
        local real dz = .At.z-.Eye.z
        local real len2d
        set .Distance = SquareRoot(dx*dx+dy*dy+dz*dz)
        set .Yaw = Atan2(dy, dx)
        set len2d = SquareRoot(dx*dx+dy*dy)
        set .Pitch = Atan2(dz, len2d)
    endmethod
   
    private method UpdateAxisMatrix takes nothing returns nothing
        local MATRIX3 mat
        call Vec3Normalize(.AxisZ, Vec3Subtract(.AxisZ, .At, .Eye))
        set mat = Matrix3RotationAxis(MATRIX3.create(), .AxisZ, -.Roll)
        call Vec3Normalize(.AxisX, Vec3Cross(.AxisX, .AxisZ, VECTOR3.oneZ))
        call Vec3Transform_1(.AxisY, Vec3Cross(.AxisY, .AxisX, .AxisZ), mat)
        call Vec3Transform_1(.AxisX, .AxisX, mat)
        call Matrix4Look(.View, .Eye, .AxisX, .AxisY, .AxisZ)
        call mat.destroy()
    endmethod

    method ApplyCameraForPlayer takes player p, boolean IgnorChange returns boolean
        if GetLocalPlayer() == p then
            call SetCameraField(CAMERA_FIELD_ROTATION, .Yaw*bj_RADTODEG, 0)
            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, .Pitch*bj_RADTODEG, 0)
            call SetCameraField(CAMERA_FIELD_ROLL, .Roll*bj_RADTODEG, 0)
            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, .Distance, 0)
            call SetCameraTargetController(AtUnit, .At.x, .At.y, false)
            call SetCameraField(CAMERA_FIELD_ZOFFSET, .At.z-DeltaZ, 0)
        endif
        if .change or IgnorChange then
            set .change = false
            return true
        endif
        return false
    endmethod

    method SetPosition takes real x, real y, real z returns nothing
        local real dx = x-.At.x
        local real dy = y-.At.y
        local real dz = z-.At.z
        set .Eye.x = .Eye.x+dx
        set .Eye.y = .Eye.y+dy
        set .Eye.z = .Eye.z+dz
        set .At.x = x
        set .At.y = y
        set .At.z = z
        set .change = true
    endmethod
   
    method SetEyeAndAt takes real ex, real ey, real ez, real tx, real ty, real tz returns nothing
        set .Eye.x = ex
        set .Eye.y = ey
        set .Eye.z = ez
        set .At.x = tx
        set .At.y = ty
        set .At.z = tz
        call .UpdateDistanceYawPitch()
        call .UpdateAxisMatrix()
        set .change = true
    endmethod
   
    method SetYawPitchRoll takes real yaw, real pitch, real roll, boolean EyeLock returns nothing
        local real Z = .Distance*Sin(pitch)
        local real XY = .Distance*Cos(pitch)
        local real X = XY*Cos(yaw)
        local real Y = XY*Sin(yaw)
        set .Yaw = yaw
        set .Pitch = pitch
        set .Roll = roll
        if EyeLock then
            set .At.x = .Eye.x+X
            set .At.y = .Eye.y+Y
            set .At.z = .Eye.z+Z
        else
            set .Eye.x = .At.x-X
            set .Eye.y = .At.y-Y
            set .Eye.z = .At.z-Z
        endif
        call .UpdateAxisMatrix()
        set .change = true
    endmethod
   
    static method New takes nothing returns CAMERA
        local CAMERA this = CAMERA.create()
        set .CostumValue = 0
        set .change = true
        set .Eye = VECTOR3.New_1(0.0,-922.668,DeltaZ+1367.912)
        set .At = VECTOR3.New_1(0, 0, DeltaZ)
        set .Distance = 0
        set .Yaw = 0
        set .Pitch = 0
        set .Roll = 0
        set .AxisX = VECTOR3.create()
        set .AxisY = VECTOR3.create()
        set .AxisZ = VECTOR3.create()
        set .View  = MATRIX4.create()
        set .Projection = Matrix4Perspective2(MATRIX4.create(), 0.5, 10000, -WidthScreen/2, WidthScreen/2, -HeightScreen/2, HeightScreen/2)
        call .UpdateDistanceYawPitch()
        call .UpdateAxisMatrix()
        return this
    endmethod
   
    method Delete takes nothing returns nothing
        call .Eye.destroy()
        call .At.destroy()
        call .AxisX.destroy()
        call .AxisY.destroy()
        call .AxisZ.destroy()
        call .View.destroy()
        call .Projection.destroy()
        call this.destroy()
    endmethod
   
endstruct

globals
    private real TempX = 0
    private real TempY = 0
endglobals
private function InitDeltaZ_Timer takes nothing returns nothing
    set DeltaZ = GetCameraTargetPositionZ()
    call SetCameraPosition(TempX, TempY)
    call DestroyTimer(GetExpiredTimer())
endfunction
function InitDeltaZ takes nothing returns nothing
    set TempX = GetCameraTargetPositionX()
    set TempY = GetCameraTargetPositionY()
    call SetCameraPosition(0, 0)
    call TimerStart(CreateTimer(), 0.04, false, function InitDeltaZ_Timer)
endfunction

private function Init takes nothing returns nothing
    set AtUnit = CreateUnit(Player(15), TypeUnit, 0, 0, 0)
    call ShowUnit(AtUnit, false)
    call InitDeltaZ()
endfunction

endlibrary