• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Using Oppi Cam with DGUI

Status
Not open for further replies.
Level 11
Joined
Jun 30, 2008
Messages
580
How would I set this up?

I want to use the Oppi Cam (Found Here) with the DGUI librarys. I am having a hard time trying to find out how to do this.

Here is Oppi Cam's Library for Third Person Cams:

JASS:
library ThirdPersonCam initializer Init

    globals
        //*****************************************************************************
        // CONSTANTS:
        private constant real DISTANCE_AOA_MIN      = -15
        private constant real DISTANCE_DISTANCE_MIN = 300
        private constant real DISTANCE_AOA_MAX      = -65
        private constant real DISTANCE_DISTANCE_MAX = 500
        private constant real OFFSET_AOA_MIN        = -35
        private constant real OFFSET_OFFSET_MIN     = 0
        private constant real OFFSET_AOA_MAX        = -70
        private constant real OFFSET_OFFSET_MAX     = 150
        
        private constant real Z_OFFSET            = 100
        private constant real TIMEOUT             = 0.1
        private constant real TERRAIN_SAMPLING    = 32
        private constant real PAN_DURATION        = 0.5
        private constant real ANGLE_ABOVE_TERRAIN = 15
        private constant real DEFAULT_AOA         = -20
        private constant real DEFAULT_ROT         = 0
        private constant real FIELD_OF_VIEW       = 120
        private constant real FAR_Z               = 5000
        private constant real CLIFF_DISTANCE      = 500
        //
        //*****************************************************************************
        
        //*****************************************************************************
        // Public variables.
        real array ThirdPersonCamAoA
        real array ThirdPersonCamRot
        //
        //*****************************************************************************
        
        //*****************************************************************************
        // Internal variables. These should not be changed:
        private location Loc = Location(0,0)
        private unit array Unit
        private timer array FirstPan
        
        private real DistanceM = (DISTANCE_DISTANCE_MAX-DISTANCE_DISTANCE_MIN)/((DISTANCE_AOA_MAX-DISTANCE_AOA_MIN)*bj_DEGTORAD)
        private real DistanceT = DISTANCE_DISTANCE_MIN-DISTANCE_AOA_MIN*bj_DEGTORAD*DistanceM
        private real OffsetM = (OFFSET_OFFSET_MAX-OFFSET_OFFSET_MIN)/((OFFSET_AOA_MAX-OFFSET_AOA_MIN)*bj_DEGTORAD)
        private real OffsetT = OFFSET_OFFSET_MIN-OFFSET_AOA_MIN*bj_DEGTORAD*OffsetM
        //
        //*****************************************************************************
    endglobals
    
    //*****************************************************************************
    // Functions for distance and offset. These are linear mathematical functions y = mx+t.
    private function InterpolateDistance takes real angleOfAttack returns real
        if angleOfAttack <= DISTANCE_AOA_MAX*bj_DEGTORAD then
            return DISTANCE_DISTANCE_MAX
        elseif angleOfAttack >= DISTANCE_AOA_MIN*bj_DEGTORAD then
            return DISTANCE_DISTANCE_MIN
        endif
        return DistanceM * angleOfAttack + DistanceT
    endfunction

    private function InterpolateOffset takes real angleOfAttack returns real
        if angleOfAttack <= OFFSET_AOA_MAX*bj_DEGTORAD then
            return OFFSET_OFFSET_MAX
        elseif angleOfAttack >= OFFSET_AOA_MIN*bj_DEGTORAD then
            return OFFSET_OFFSET_MIN
        endif
        return OffsetM * angleOfAttack + OffsetT
    endfunction
    //
    //*****************************************************************************

    //*****************************************************************************
    // Functions for camera settings.
    private function ApplyCam takes integer p, real duration returns nothing
        local real aoa = GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK) - 2*bj_PI
        local real offset = InterpolateOffset(aoa)
        local real newaoa
        local real maxd
        local real tarz
        local real newx
        local real newy
        local real newm
        local real maxm = -1
        local real r = TERRAIN_SAMPLING
        local real dx
        local real dy
        
        call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(Unit) + ThirdPersonCamRot, duration)
        call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, FIELD_OF_VIEW, duration)
        call SetCameraField(CAMERA_FIELD_FARZ, FAR_Z, duration)
        call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, InterpolateDistance(aoa), duration)
        
        call PanCameraToTimed(GetUnitX(Unit) + offset * Cos(bj_DEGTORAD*GetUnitFacing(Unit)), GetUnitY(Unit) + offset * Sin(bj_DEGTORAD*GetUnitFacing(Unit)), duration)
        
        set newx = GetCameraTargetPositionX()
        set newy = GetCameraTargetPositionY()
        set maxd = CLIFF_DISTANCE+GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
        set dx = -Cos(GetCameraField(CAMERA_FIELD_ROTATION))*r
        set dy = -Sin(GetCameraField(CAMERA_FIELD_ROTATION))*r
        
        call MoveLocation(Loc, newx, newy)
        set tarz = GetCameraTargetPositionZ()
        call SetCameraField(CAMERA_FIELD_ZOFFSET, GetCameraField(CAMERA_FIELD_ZOFFSET) + GetLocationZ(Loc) + Z_OFFSET + GetUnitFlyHeight(Unit) - tarz, duration)
                
        loop
            exitwhen r > maxd
            set newx = newx+dx
            set newy = newy+dy
            call MoveLocation(Loc, newx, newy)
            set newm = (GetLocationZ(Loc)-tarz)/r
            if newm > maxm then
                set maxm = newm
            endif
            set r = r+TERRAIN_SAMPLING
        endloop
        set newaoa = - Atan(maxm) * bj_RADTODEG - ANGLE_ABOVE_TERRAIN
        if ThirdPersonCamAoA < newaoa then
            set newaoa = ThirdPersonCamAoA
        endif
        call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, newaoa, duration)
    endfunction
    
    private function Periodic takes nothing returns nothing
        local integer p = GetPlayerId(GetLocalPlayer())
        
        if Unit != null then
            if TimerGetRemaining(FirstPan) <= PAN_DURATION then
                call ApplyCam(p, PAN_DURATION)
            else
                call ApplyCam(p, TimerGetRemaining(FirstPan))
            endif
        endif
    endfunction
    //
    //*****************************************************************************
    
    //*****************************************************************************
    // Public functions.
    function EnableThirdPersonCam takes player whichPlayer, unit whichUnit, real firstPan returns nothing
        local integer p = GetPlayerId(whichPlayer)
        
        set Unit = whichUnit
        call TimerStart(FirstPan, firstPan, false, null)
        if GetLocalPlayer() == Player(p) then
            call StopCamera()
            if whichUnit != null then
                call ApplyCam(p, firstPan)
            endif
        endif
    endfunction
    
    function IsThirdPersonCamActive takes integer p returns boolean
        return Unit != null
    endfunction
    
    function ResetThirdPersonCamAoA takes integer p returns nothing
        set ThirdPersonCamAoA = DEFAULT_AOA
    endfunction
    
    function ResetThirdPersonCamRot takes integer p returns nothing
        set ThirdPersonCamRot = DEFAULT_ROT
    endfunction
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //Init function for timer and arrays.
    private function Init takes nothing returns nothing
        local timer t = CreateTimer()
        local integer i = 0
        
        loop
            exitwhen i == 12
            set ThirdPersonCamAoA[i] = DEFAULT_AOA
            set ThirdPersonCamRot[i] = DEFAULT_ROT
            set Unit[i] = null
            set FirstPan[i] = CreateTimer()
            set i = i+1
        endloop
        
        call TimerStart(t, TIMEOUT, true, function Periodic)
        
        set t = null
    endfunction
    //
    //*****************************************************************************

endlibrary

And here is the DGUI and Camera Libraries

JASS:
library DGUI requires Math, Camera

globals
    private constant integer TypeUnit = 'dgui'
    private integer TypeSkinChanger = 'A000'
    private BUTTON TriggerButton
    private location GL4DGUI = Location(0,0)
endglobals

function GetTriggerButton takes nothing returns BUTTON
    return TriggerButton
endfunction

private function GetZ4DGUI takes real X, real Y returns real
    call MoveLocation(GL4DGUI, X, Y)
    return GetLocationZ(GL4DGUI)
endfunction

private function FineIndexAnimModel takes real w, real h, real z returns integer
    local real W = w*WidthScreen*z
    local real H = h*HeightScreen*z
    local real anim
    if (H<W) then
        set anim = 10*(W/H-1)
        return R2I_n(anim)
    else
        set anim = 10*(H/W-1)
        if anim >= 0.5 then
            return 100+R2I_n(anim)
        endif
    endif
    return 0
endfunction

private function FineSizeModel takes real w, real h, real z returns real
    local real W = w*WidthScreen*z
    local real H = h*HeightScreen*z
    if (H<W) then
        return 0.5*H
    else
        return 0.5*W
    endif
endfunction

struct BUTTON
    static BUTTON array AllShow
    static integer CountShow = 0
    private integer index
    private CAMERA Camera
    
    private real centerx
    private real centery
    private real minx
    private real maxx
    private real miny
    private real maxy
    private real width
    private real height
    private real z
    unit picture
    private integer indexanim
    private effect model
    private trigger trigLclick
    private trigger trigRclick
    boolean show
    integer CostumValue
 
    static method New takes real minx, real maxy, real W, real H, real z, integer texture returns BUTTON
        local BUTTON this = BUTTON.create()
        local destructable tree
        set .CostumValue = 0
        set .Camera = 0
        set .width = W
        set .height = H
        set .minx = minx
        set .maxx = minx+W
        set .maxy = maxy
        set .miny = maxy-H
        set .z = 100.2+z
        set .centerx = minx+W/2.0
        set .centery = maxy-H/2.0
        set .show = false
        set .trigLclick = CreateTrigger()
        set .trigRclick = CreateTrigger()
        set .picture = CreateUnit(Player(15), TypeUnit, 0, 0, 0)
        call UnitAddAbility(.picture, TypeSkinChanger)
        if (texture != 0) then
            set tree = CreateDestructable(texture,0,0,0,0,1)
            call IssueTargetOrder(.picture, "grabtree", tree)
            call RemoveDestructable(tree)
            set tree = null
        endif
        set .indexanim = FineIndexAnimModel(W, H, .z)
        call SetUnitAnimationByIndex(.picture, .indexanim)
        call SetUnitScale(.picture, FineSizeModel(W, H, .z), 0, 0)
        call UnitAddAbility(.picture, 'Aave')
        call UnitRemoveAbility(.picture, 'Aave')
        call ShowUnit(.picture, false)
        call SetUnitUserData(.picture, this)
        return this
    endmethod

    method AddActionL takes code func returns triggeraction
        return TriggerAddAction(.trigLclick, func)
    endmethod
    
    method RemoveActionL takes triggeraction action returns nothing
        call TriggerRemoveAction(.trigLclick, action)
    endmethod
    
    method AddActionR takes code func returns triggeraction
        return TriggerAddAction(.trigRclick, func)
    endmethod
    
    method RemoveActionR takes triggeraction action returns nothing
        call TriggerRemoveAction(.trigRclick, action)
    endmethod
    
    method Delete takes nothing returns nothing
        call DestroyTrigger(.trigLclick)
        call DestroyTrigger(.trigRclick)
        call RemoveUnit(.picture)
        if .show then
            set .AllShow[.index] = .AllShow[.CountShow]
            set .AllShow[.index].index = .index
            set .CountShow = .CountShow - 1
        endif
    endmethod
    
    method Update takes nothing returns nothing
        local VECTOR3 Pos = .Camera.Win2World(.centerx, .centery, .z)
        call SetUnitX(.picture, Pos.x)
        call SetUnitY(.picture, Pos.y)
        call MoveLocation(GL4DGUI, Pos.x, Pos.y)
        call SetUnitFlyHeight(.picture, Pos.z-GetLocationZ(GL4DGUI), 0)
        call Pos.destroy()
    endmethod
    
    method Show takes boolean show, CAMERA Cam returns nothing
        if Cam != -1 then
            set .Camera = Cam
        endif
        call ShowUnit(.picture, show)
        if show != .show then
            if show then
                set .AllShow[.CountShow] = this
                set .index = .CountShow
                set .CountShow = .CountShow + 1
                call .Update()
                call SetUnitAnimationByIndex(.picture, .indexanim)
            else
                set .CountShow = .CountShow - 1
                set .AllShow[.index] = .AllShow[.CountShow]
                set .AllShow[.index].index = .index
            endif
        endif
        set .show = show
    endmethod
    
    method IsClick takes unit u returns boolean
        return .picture == u
    endmethod
    
    method IsClickEx takes real x, real y returns boolean
        return .minx < x and x < .maxx and .miny < y  and y < .maxy
    endmethod
    
    method ClickL takes nothing returns nothing
        set TriggerButton = this
        call TriggerExecute(.trigLclick)
    endmethod
    
    method ClickR takes nothing returns nothing
        set TriggerButton = this
        call TriggerExecute(.trigRclick)
    endmethod
    
    method SetPosition takes real minx, real maxy returns nothing
        set .minx = minx
        set .maxx = minx+.width
        set .maxy = maxy
        set .miny = maxy-.height
        set .centerx = minx+.width/2.0
        set .centery = maxy-.height/2.0
        if .show then
            call .Update()
        endif
    endmethod
    
    method SetTexture takes integer texture returns nothing
        local destructable tree = CreateDestructable(texture,0,0,0,0,1)
        call ShowUnit(.picture, true)
        call SetUnitX(.picture, 0)
        call SetUnitY(.picture, 0)
        call IssueTargetOrder(.picture,"grabtree",tree)
        call ShowUnit(.picture, .show)
        call RemoveDestructable(tree)
        if .show then
            call .Update()
        endif
        set tree = null
    endmethod
    
    static method AllUpdate takes nothing returns nothing
        local integer i = .CountShow
        loop
            exitwhen i < 0
            call .AllShow[i].Update()
            set i = i - 1
        endloop
    endmethod
    
    static method Click takes unit u, boolean IsLeft returns boolean
        local BUTTON b
        if GetUnitTypeId(u) == TypeUnit then
            set b = GetUnitUserData(u)
            if b != 0 and b.show then
                if IsLeft then
                    call b.ClickL()
                else
                    call b.ClickR()
                endif
                return true
            endif
        endif
        return false
    endmethod
    
    static method ClickEx takes real x, real y, boolean IsLeft returns boolean
        local integer i = .CountShow
        loop
            exitwhen i < 0
            if .AllShow[i].IsClickEx(x, y) then
                if IsLeft then
                    call .AllShow[i].ClickL()
                else
                    call .AllShow[i].ClickR()
                endif
                return true
            endif
            set i = i - 1
        endloop
        return false
    endmethod
    
    static method ClickPeriodicSelect takes player p, boolean IsLeft returns boolean
        local integer i = .CountShow
        loop
            exitwhen i < 0
            if IsUnitSelected(.AllShow[i].picture, p) then
                if IsLeft then
                    call .AllShow[i].ClickL()
                else
                    call .AllShow[i].ClickR()
                endif
                return true
            endif
            set i = i - 1
        endloop
        return false
    endmethod

endstruct

function DGUIClickEx takes real x, real y, boolean IsLeft returns boolean
    local integer i = BUTTON.CountShow
    loop
        exitwhen i < 0
        if BUTTON.AllShow[i].IsClickEx(x, y) then
            if IsLeft then
                call BUTTON.AllShow[i].ClickL()
            else
                call BUTTON.AllShow[i].ClickR()
            endif
            return true
        endif
        set i = i - 1
    endloop
    return false
endfunction

struct PICTURE
    private static PICTURE array AllShow
    private static integer CountShow = 0
    private integer index
    private CAMERA Camera
    
    private real centerx
    private real centery
    private real width
    private real height
    private real z
    unit picture
    private integer indexanim
    boolean show
    integer CostumValue
    
    static method New takes real minx, real maxy, real W, real H, real z, integer texture returns PICTURE
        local PICTURE this = PICTURE.create()
        local destructable tree
        set .CostumValue = 0
        set .Camera = 0
        set .width = W
        set .height = H
        set .centerx = minx+W/2.0
        set .centery = maxy-H/2.0
        set .z = 100.2+z
        set .show = false
        set .picture = CreateUnit(Player(15), TypeUnit, 0, 0, 0)
        call UnitAddAbility(.picture, TypeSkinChanger)
        if (texture != 0) then
            set tree = CreateDestructable(texture,0,0,0,0,1)
            call IssueTargetOrder(.picture, "grabtree", tree)
            call RemoveDestructable(tree)
            set tree = null
        endif
        set .indexanim = FineIndexAnimModel(W, H, .z)
        call SetUnitAnimationByIndex(.picture, .indexanim)
        call SetUnitScale(.picture, FineSizeModel(W, H, .z), 0, 0)
        call UnitAddAbility(.picture, 'Aave')
        call UnitRemoveAbility(.picture, 'Aave')
        call UnitAddAbility(.picture, 'Aloc')
        call UnitRemoveAbility(.picture, 'Aloc')
        call ShowUnit(.picture, false)
        return this
    endmethod
    
    static method NewCostumModel takes real minx, real maxy, real z, real size, integer typeunit, real WidthModel, real HeightModel, integer texture returns PICTURE
        local PICTURE this = PICTURE.create()
        local destructable tree
        set .CostumValue = 0
        set .Camera = 0
        set .z = 100.2+z
        set .width = (WidthModel*size)/(WidthScreen*.z)
        set .height = (HeightModel*size)/(HeightScreen*.z)
        set .centerx = minx+.width/2.0
        set .centery = maxy-.height/2.0
        set .show = false
        set .picture = CreateUnit(Player(15), typeunit, 0, 0, 0)
        call UnitAddAbility(.picture, TypeSkinChanger)
        if (texture != 0) then
            set tree = CreateDestructable(texture,0,0,0,0,1)
            call IssueTargetOrder(.picture, "grabtree", tree)
            call RemoveDestructable(tree)
            set tree = null
        endif
        call SetUnitScale(.picture, size, 0, 0)
        call UnitAddAbility(.picture, 'Aave')
        call UnitRemoveAbility(.picture, 'Aave')
        call UnitAddAbility(.picture, 'Aloc')
        call UnitRemoveAbility(.picture, 'Aloc')
        call ShowUnit(.picture, false)
        return this
    endmethod
    
    method Delete takes nothing returns nothing
        call RemoveUnit(.picture)
        if .show then
            set .AllShow[.index] = .AllShow[.CountShow]
            set .AllShow[.index].index = .index
            set .CountShow = .CountShow - 1
        endif
    endmethod
    
    method Update takes nothing returns nothing
        local VECTOR3 Pos = .Camera.Win2World(.centerx, .centery, .z)
        call SetUnitX(.picture, Pos.x)
        call SetUnitY(.picture, Pos.y)
        call MoveLocation(GL4DGUI, Pos.x, Pos.y)
        call SetUnitFlyHeight(.picture, Pos.z-GetLocationZ(GL4DGUI), 0)
        call Pos.destroy()
    endmethod
    
    method Show takes boolean show, CAMERA Cam returns nothing
        if Cam != -1 then
            set .Camera = Cam
        endif
        call ShowUnit(.picture, show)
        if show != .show then
            if show then
                set .AllShow[.CountShow] = this
                set .index = .CountShow
                set .CountShow = .CountShow + 1
                call .Update()
                call SetUnitAnimationByIndex(.picture, .indexanim)
                call UnitAddAbility(.picture, 'Aloc')
                call UnitRemoveAbility(.picture, 'Aloc')
            else
                set .CountShow = .CountShow - 1
                set .AllShow[.index] = .AllShow[.CountShow]
                set .AllShow[.index].index = .index
            endif
        endif
        set .show = show
    endmethod
    
    method SetPosition takes real minx, real maxy returns nothing
        set .centerx = minx+.width/2.0
        set .centery = maxy-.height/2.0
        if .show then
            call .Update()
        endif
    endmethod
    
    method SetTexture takes integer texture returns nothing
        local destructable tree = CreateDestructable(texture,0,0,0,0,1)
        call ShowUnit(.picture, true)
        call SetUnitX(.picture, 0)
        call SetUnitY(.picture, 0)
        call IssueTargetOrder(.picture,"grabtree",tree)
        call ShowUnit(.picture, .show)
        call RemoveDestructable(tree)
        if .show then
            call .Update()
        endif
        set tree = null
    endmethod
    
    static method AllUpdate takes nothing returns nothing
        local integer i = .CountShow
        loop
            exitwhen i < 0
            call .AllShow[i].Update()
            set i = i - 1
        endloop
    endmethod

endstruct

struct TEXT
    private static TEXT array AllShow
    private static integer CountShow = 0
    private integer index
    private CAMERA Camera
    
    private real minx
    private real maxy
    private real z
    texttag text
    boolean show
    integer CostumValue
    
    static method New takes real minx, real maxy, real z returns TEXT
        local TEXT this = TEXT.create()
        set .CostumValue = 0
        set .Camera = 0
        set .minx = minx
        set .maxy = maxy
        set .z = 100+z
        set .show = false
        set .text = CreateTextTag()
        call SetTextTagVisibility(.text, false)
        return this
    endmethod
    
    method Delete takes nothing returns nothing
        call DestroyTextTag(.text)
        if .show then
            set .AllShow[.index] = .AllShow[.CountShow]
            set .AllShow[.index].index = .index
            set .CountShow = .CountShow - 1
        endif
    endmethod
    
    method Update takes nothing returns nothing
        local VECTOR3 Pos = .Camera.Win2World(.minx, .maxy, .z)
        call SetTextTagPos(.text, Pos.x, Pos.y, Pos.z-GetZ4DGUI(Pos.x,Pos.y))
        call Pos.destroy()
    endmethod
    
    method SetPosition takes real minx, real maxy returns nothing
        set .minx = minx
        set .maxy = maxy
        if .show then
            call .Update()
        endif
    endmethod
    
    method Show takes boolean show, CAMERA Cam returns nothing
        if Cam != -1 then
            set .Camera = Cam
        endif
        call SetTextTagVisibility(.text, show)
        if show != .show then
            if show then
                set .AllShow[.CountShow] = this
                set .index = .CountShow
                set .CountShow = .CountShow + 1
                call .Update()
            else
                set .CountShow = .CountShow - 1
                set .AllShow[.index] = .AllShow[.CountShow]
                set .AllShow[.index].index = .index
            endif
        endif
        set .show = show
    endmethod
    
    static method AllUpdate takes nothing returns nothing
        local integer i = .CountShow
        loop
            exitwhen i < 0
            call .AllShow[i].Update()
            set i = i - 1
        endloop
    endmethod

endstruct

function DGUIUpdate takes boolean but, boolean pic, boolean tex returns nothing
    if but then
        call BUTTON.AllUpdate()
    endif
    if pic then
        call PICTURE.AllUpdate()
    endif
    if tex then
        call TEXT.AllUpdate()
    endif
endfunction

endlibrary

and Camera

JASS:
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
 
Level 7
Joined
Dec 3, 2006
Messages
339
I can see why your having issues with this. It's not really that easy since both DGUI/CAMERA and Oppicam are kinda math intensive. I was thinking of doing this sorta thing for my map; but haven't implemented anything using DGUI yet.

JASS:
    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

This function is what you basically need to focus on for changing the DGUI camera to run like Oppicam. Basically replacing it and modifying some of the vectors.
Note: It is using vectors to calculate the camera for DGUI; so you might want to recode the Camera library to use a vector library like this: http://www.wc3c.net/showthread.php?t=87027

And the hard part: Also you will probably need to change the update functions to somewhat that of Oppicam but pass the correct parameters to the right parts of the Camera vectors for it to work correctly. And without some good knowledge of how DGUI's camera works could leave you in a mess of a hole.
Note: As far as I can see it is probably easier to set up the Oppicam Fixed Camera to run off of DGUI Camera rather than the Oppicam Third Person Camera because it's less math intensive.



The easy part-- Vectors as cameras should be pretty simple: Basically Angle of Attack(AOA) will be the angle of the vector, and x, y , z are pretty self explanatory.


For example this would be all one vector:

(I'm not sure about this part; but it seems somewhat reasonable; I'll figure it out probably just not looking at it right enough to tell atm.)

JASS:
        private constant real DISTANCE_AOA_MIN      = -15 //minimum angle
        private constant real DISTANCE_DISTANCE_MIN = 300 //min dist x/y
        private constant real DISTANCE_AOA_MAX      = -65 //maximum angle
        private constant real DISTANCE_DISTANCE_MAX = 500//max dist x/y

and so would this:

JASS:
        private constant real OFFSET_AOA_MIN        = -35 //minimum angle
        private constant real OFFSET_OFFSET_MIN     = 0 //min dist x,y
        private constant real OFFSET_AOA_MAX        = -70 //maximum angle
        private constant real OFFSET_OFFSET_MAX     = 150// max dist x,y

For a tutorial on pitch, roll, and yaw which could be required since Camera uses it for the vectors ->http://world-editor-tutorials.thehelper.net/cat_usersubmit.php?view=145620
 
Last edited:
I haven't checked, but doesn't DGUI require some manipulation of the objects on screen as well? (also, is the DGUI model billboarded?) I don't know if it does it in relation to the camera, though. If it does, then just changing the function as switch said would probably do the trick. Otherwise, it might require more manipulation.

IMO, try to experiment with the function that switch provided and see if everything is still in place. You might not be able to get all of Oppicam's effects but you may be able to at least achieve the proper perspectives.
 
Level 11
Joined
Jun 30, 2008
Messages
580
Wouldn't the DGUI camera system be simpler if it just took the data from current cam data during real time? That way the DGUI will stay in place no matter what cam position it is in?

I feel like this is simple to do, just finding where to start is whats difficult.
 
Status
Not open for further replies.
Top