Camera

Scripts

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

Code (jass) Select
1
2
library Camera initializer Init requires Math
3
4
globals
5
    private constant integer TypeUnit = 'dgui'
6
    private location GL4Cam = Location(0,0)
7
    private unit AtUnit = null
8
    private real DeltaZ = 0
9
endglobals
10
11
globals
12
    constant real WidthScreen = 0.544
13
    constant real HeightScreen = 0.302
14
    constant real AspectRatio = WidthScreen/HeightScreen
15
endglobals
16
17
private function Matrix4Perspective1 takes MATRIX4 Output, real fovy, real Aspect, real zn, real zf returns MATRIX4
18
    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)
19
endfunction
20
21
private function Matrix4Perspective2 takes MATRIX4 Output, real n, real f, real r, real l, real t, real b returns MATRIX4
22
    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)
23
endfunction
24
25
private function Matrix4Look takes MATRIX4 Output, VECTOR3 PosCamera, VECTOR3 AxisX, VECTOR3 AxisY, VECTOR3 AxisZ returns MATRIX4
26
    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)
27
endfunction
28
29
struct CAMERA
30
    VECTOR3 Eye
31
    VECTOR3 At
32
    real Distance
33
    real Yaw
34
    real Pitch
35
    real Roll
36
    VECTOR3 AxisX
37
    VECTOR3 AxisY
38
    VECTOR3 AxisZ
39
    private MATRIX4 View
40
    private MATRIX4 Projection
41
    private boolean change
42
    integer CostumValue
43
    
44
    method Win2World takes real X, real Y, real Range returns VECTOR3
45
        local VECTOR3 Output = VECTOR3.create()
46
        set Output.x = .Eye.x+.AxisZ.x*Range+X*.AxisX.x*WidthScreen*Range+Y*.AxisY.x*HeightScreen*Range
47
        set Output.y = .Eye.y+.AxisZ.y*Range+X*.AxisX.y*WidthScreen*Range+Y*.AxisY.y*HeightScreen*Range
48
        set Output.z = .Eye.z+.AxisZ.z*Range+X*.AxisX.z*WidthScreen*Range+Y*.AxisY.z*HeightScreen*Range
49
        return Output
50
    endmethod
51
52
    method World2Win takes real X, real Y, real Z returns VECTOR3
53
        local VECTOR3 Pos = VECTOR3.New_1(X, Y, Z)
54
        local boolean b
55
        call Vec3Transform_2(Pos, Pos, .View)
56
        set b = Pos.z < 0
57
        call Vec3Transform_2(Pos, Pos, .Projection)
58
        if b then
59
            set Pos.z = -Pos.z
60
        endif
61
        return Pos
62
    endmethod
63
    
64
    private method UpdateDistanceYawPitch takes nothing returns nothing
65
        local real dx = .At.x-.Eye.x
66
        local real dy = .At.y-.Eye.y
67
        local real dz = .At.z-.Eye.z
68
        local real len2d
69
        set .Distance = SquareRoot(dx*dx+dy*dy+dz*dz)
70
        set .Yaw = Atan2(dy, dx)
71
        set len2d = SquareRoot(dx*dx+dy*dy)
72
        set .Pitch = Atan2(dz, len2d)
73
    endmethod
74
    
75
    private method UpdateAxisMatrix takes nothing returns nothing
76
        local MATRIX3 mat
77
        call Vec3Normalize(.AxisZ, Vec3Subtract(.AxisZ, .At, .Eye))
78
        set mat = Matrix3RotationAxis(MATRIX3.create(), .AxisZ, -.Roll)
79
        call Vec3Normalize(.AxisX, Vec3Cross(.AxisX, .AxisZ, VECTOR3.oneZ))
80
        call Vec3Transform_1(.AxisY, Vec3Cross(.AxisY, .AxisX, .AxisZ), mat)
81
        call Vec3Transform_1(.AxisX, .AxisX, mat)
82
        call Matrix4Look(.View, .Eye, .AxisX, .AxisY, .AxisZ)
83
        call mat.destroy()
84
    endmethod
85
86
    method ApplyCameraForPlayer takes player p, boolean IgnorChange returns boolean
87
        if GetLocalPlayer() == p then
88
            call SetCameraField(CAMERA_FIELD_ROTATION, .Yaw*bj_RADTODEG, 0)
89
            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, .Pitch*bj_RADTODEG, 0)
90
            call SetCameraField(CAMERA_FIELD_ROLL, .Roll*bj_RADTODEG, 0)
91
            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, .Distance, 0)
92
            call SetCameraTargetController(AtUnit, .At.x, .At.y, false)
93
            call SetCameraField(CAMERA_FIELD_ZOFFSET, .At.z-DeltaZ, 0)
94
        endif
95
        if .change or IgnorChange then
96
            set .change = false
97
            return true
98
        endif
99
        return false
100
    endmethod
101
102
    method SetPosition takes real x, real y, real z returns nothing
103
        local real dx = x-.At.x
104
        local real dy = y-.At.y
105
        local real dz = z-.At.z
106
        set .Eye.x = .Eye.x+dx
107
        set .Eye.y = .Eye.y+dy
108
        set .Eye.z = .Eye.z+dz
109
        set .At.x = x
110
        set .At.y = y
111
        set .At.z = z
112
        set .change = true
113
    endmethod
114
    
115
    method SetEyeAndAt takes real ex, real ey, real ez, real tx, real ty, real tz returns nothing
116
        set .Eye.x = ex
117
        set .Eye.y = ey
118
        set .Eye.z = ez
119
        set .At.x = tx
120
        set .At.y = ty
121
        set .At.z = tz
122
        call .UpdateDistanceYawPitch()
123
        call .UpdateAxisMatrix()
124
        set .change = true
125
    endmethod
126
    
127
    method SetYawPitchRoll takes real yaw, real pitch, real roll, boolean EyeLock returns nothing
128
        local real Z = .Distance*Sin(pitch)
129
        local real XY = .Distance*Cos(pitch)
130
        local real X = XY*Cos(yaw)
131
        local real Y = XY*Sin(yaw)
132
        set .Yaw = yaw
133
        set .Pitch = pitch
134
        set .Roll = roll
135
        if EyeLock then
136
            set .At.x = .Eye.x+X
137
            set .At.y = .Eye.y+Y
138
            set .At.z = .Eye.z+Z
139
        else
140
            set .Eye.x = .At.x-X
141
            set .Eye.y = .At.y-Y
142
            set .Eye.z = .At.z-Z
143
        endif
144
        call .UpdateAxisMatrix()
145
        set .change = true
146
    endmethod
147
    
148
    static method New takes nothing returns CAMERA
149
        local CAMERA this = CAMERA.create()
150
        set .CostumValue = 0
151
        set .change = true
152
        set .Eye = VECTOR3.New_1(0.0,-922.668,DeltaZ+1367.912)
153
        set .At = VECTOR3.New_1(0, 0, DeltaZ)
154
        set .Distance = 0
155
        set .Yaw = 0
156
        set .Pitch = 0
157
        set .Roll = 0
158
        set .AxisX = VECTOR3.create()
159
        set .AxisY = VECTOR3.create()
160
        set .AxisZ = VECTOR3.create()
161
        set .View  = MATRIX4.create()
162
        set .Projection = Matrix4Perspective2(MATRIX4.create(), 0.5, 10000, -WidthScreen/2, WidthScreen/2, -HeightScreen/2, HeightScreen/2)
163
        call .UpdateDistanceYawPitch()
164
        call .UpdateAxisMatrix()
165
        return this
166
    endmethod
167
    
168
    method Delete takes nothing returns nothing
169
        call .Eye.destroy()
170
        call .At.destroy()
171
        call .AxisX.destroy()
172
        call .AxisY.destroy()
173
        call .AxisZ.destroy()
174
        call .View.destroy()
175
        call .Projection.destroy()
176
        call this.destroy()
177
    endmethod
178
    
179
endstruct
180
181
globals
182
    private real TempX = 0
183
    private real TempY = 0
184
endglobals
185
private function InitDeltaZ_Timer takes nothing returns nothing
186
    set DeltaZ = GetCameraTargetPositionZ()
187
    call SetCameraPosition(TempX, TempY)
188
    call DestroyTimer(GetExpiredTimer())
189
endfunction
190
function InitDeltaZ takes nothing returns nothing
191
    set TempX = GetCameraTargetPositionX()
192
    set TempY = GetCameraTargetPositionY()
193
    call SetCameraPosition(0, 0)
194
    call TimerStart(CreateTimer(), 0.04, false, function InitDeltaZ_Timer)
195
endfunction
196
197
private function Init takes nothing returns nothing
198
    set AtUnit = CreateUnit(Player(15), TypeUnit, 0, 0, 0)
199
    call ShowUnit(AtUnit, false)
200
    call InitDeltaZ()
201
endfunction
202
203
endlibrary