14 years
edited 8 years
Camera library to ease camera setup and control.
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