• 🏆 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!

[System] GetCamOffset

Level 10
Joined
May 26, 2005
Messages
194
GetCamOffset(x,y) is the only function to access from outside the library.
It returns the camera z offset on a given terrain position, useful for placing the camera correctly for 3rd person cams and so on...
however, does not work for destructables with an overfly-z-size, nor for water

for everything else, it works so precise that you wont see any inaccuracy with your eyes, i made a 3d flight simulator using it, and the cam sticks to the plane very well

Demo map:
http://www.hiveworkshop.com/forums/maps-564/flightsim-concept-131344/

JASS:
library GetCamOffset initializer cameramapInit
    globals
        private location cameramapLoc
        private real array camOffset[90][90]
        private real mapMinX
        private real mapMinY
        private real mapMaxX
        private real mapMaxY
    endglobals
    
    private function GetGridCamOffset takes integer ix, integer iy, integer offx, integer offy returns real
        local real r
        local integer ixl = ix-1
        local integer ixr = ix+1
        local integer iyd = iy-1
        local integer iyu = iy+1
        if ixl<0 then
            set ixl = 0
        endif
        if iyd<0 then
            set iyd = 0
        endif
        if ixr>256 then
            set ixr=256
        endif
        if iyu>256 then
            set iyu=256
        endif
        if offx>0 then
            if offy>0 then
                set r =   .089696*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .097349*camOffset[ixr][iyu]
                set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
                set r = r+.082587*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .082587*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
                set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
                set r = r+.089696*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .097349*camOffset[ixr][iyd]
            else
                set r =   .084604*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
                set r = r+.134017*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .142877*camOffset[ixr][iy]
                set r = r+.084604*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
            endif
        elseif offx<0 then
            if offy>0 then
                set r =   .097349*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
                set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
                set r = r+.089696*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .082587*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .089696*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .082587*camOffset[ixr][iyu]
                set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
                set r = r+.097349*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
            else
                set r =   .091913*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
                set r = r+.142877*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134017*camOffset[ixr][iy]
                set r = r+.091913*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
            endif
        else
            if offy>0 then
                set r =   .091913*camOffset[ixl][iyu]+ .142877*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
                set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]
                set r = r+.084604*camOffset[ixl][iyd]+ .134017*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .084604*camOffset[ixl][iyu]+ .134017*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
                set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]                
                set r = r+.091913*camOffset[ixl][iyd]+ .142877*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
            else
                set r =   .086125*camOffset[ixl][iyu]+ .136429*camOffset[ix][iyu]+ .086125*camOffset[ixr][iyu]
                set r = r+.136429*camOffset[ixl][iy] + .109784*camOffset[ix][iy] + .136429*camOffset[ixr][iy]
                set r = r+.086125*camOffset[ixl][iyd]+ .136429*camOffset[ix][iyd]+ .086125*camOffset[ixr][iyd]
            endif
        endif
        return r
    endfunction
    
    function GetCamOffset takes real x, real y returns real
        local integer iXLo = R2I((x-mapMinX)/512.+.5)
        local integer iYLo = R2I((y-mapMinY)/512.+.5)
        local integer iXHi = iXLo+1
        local integer iYHi = iYLo+1
        local integer iChkXLo
        local integer iChkXLoOff
        local integer iChkXHi
        local integer iChkXHiOff
        local integer iChkYLo
        local integer iChkYLoOff
        local integer iChkYHi
        local integer iChkYHiOff
        local real XLo
        local real YLo
        local real XHi
        local real YHi
        local real rX
        local real rY
        local real r
        local real LoDX = (x-mapMinX)-(iXLo*512.-256.)
        local real LoDY = (y-mapMinY)-(iYLo*512.-256.)
        if LoDX<=12 then
            set iChkXLo = iXLo
            set iChkXLoOff = 0
            set iChkXHi = iXLo
            set iChkXHiOff = 1
        elseif LoDX<500 then
            set iChkXLo = iXLo
            set iChkXLoOff = 1
            set iChkXHi = iXHi
            set iChkXHiOff =-1
        else
            set iChkXLo = iXHi
            set iChkXLoOff =-1
            set iChkXHi = iXHi
            set iChkXHiOff = 0
        endif
        if LoDY<=12 then
            set iChkYLo = iYLo
            set iChkYLoOff = 0
            set iChkYHi = iYLo
            set iChkYHiOff = 1
        elseif LoDY<500 then
            set iChkYLo = iYLo
            set iChkYLoOff = 1
            set iChkYHi = iYHi
            set iChkYHiOff =-1
        else
            set iChkYLo = iYHi
            set iChkYLoOff =-1
            set iChkYHi = iYHi
            set iChkYHiOff = 0
        endif
        set XLo = iChkXLo*512.+iChkXLoOff*12.-256.
        set XHi = iChkXHi*512.+iChkXHiOff*12.-256.
        set YLo = iChkYLo*512.+iChkYLoOff*12.-256.
        set YHi = iChkYHi*512.+iChkYHiOff*12.-256.
        set rX = ((x-mapMinX)-XLo)/(XHi-XLo)
        set rY = ((y-mapMinY)-YLo)/(YHi-YLo)
        set r =   GetGridCamOffset(iChkXHi,iChkYHi,iChkXHiOff,iChkYHiOff)*rX*rY
        set r = r+GetGridCamOffset(iChkXLo,iChkYHi,iChkXLoOff,iChkYHiOff)*(1-rX)*rY
        set r = r+GetGridCamOffset(iChkXHi,iChkYLo,iChkXHiOff,iChkYLoOff)*rX*(1-rY)
        set r = r+GetGridCamOffset(iChkXLo,iChkYLo,iChkXLoOff,iChkYLoOff)*(1-rX)*(1-rY)
        return r
    endfunction
    
    private function cameramapInit_GridSub takes real x, real y returns real
        local integer index
        local integer iX = -6
        local integer iY
        local real z
        local real r
        local real i = 64 //9*4+12*2+4
        call MoveLocation(cameramapLoc,x,y)
        set z = GetLocationZ(cameramapLoc)
        set r = 0.
        call MoveLocation(cameramapLoc,x-128.,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x-128.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x-128.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        
        call MoveLocation(cameramapLoc,x-256.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x-256.,y)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x-256.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x+256.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+256.,y)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+256.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x-128.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+128.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x-128.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+128.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x+256.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x+256.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x-256.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x-256.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        return r
    endfunction
    
    private function cameramapInit_DoRow takes nothing returns nothing
        local real x = mapMinX+256.
        local real y = mapMinY+256.
        local integer iX = bj_forLoopAIndex
        local integer iY = 0
        loop
            exitwhen y+iY*512.>mapMaxY
            set camOffset[(iX+1)][iY+1] = cameramapInit_GridSub(x+iX*512.,y+iY*512.)
            set iY = iY + 1
        endloop
    endfunction

    private function cameramapInit takes nothing returns nothing
        local real x
        local real y
        local integer iX = 0
        local integer iY
        local rect map = GetWorldBounds()
        set mapMinX = GetRectMinX(map)
        set mapMinY = GetRectMinY(map)
        set mapMaxX = GetRectMaxX(map)
        set mapMaxY = GetRectMaxY(map)
        call RemoveRect(map)
        set map = null
        set x = mapMinX+256.
        set y = mapMinY+256.
        set cameramapLoc = Location(0,0)
        loop
            exitwhen x+iX*512.>mapMaxX
            set bj_forLoopAIndex = iX
            call ExecuteFunc("cameramapInit_DoRow")
            set iX = iX + 1
        endloop
        call RemoveLocation(cameramapLoc)
        set cameramapLoc = null
    endfunction
endlibrary
 
Last edited by a moderator:
Level 10
Joined
May 26, 2005
Messages
194
MapperMalte, you are wrong...
GetLocationZ() returns the Z of the terrain, but not of the camera on this position

warcraft 3 flattens the camera movement so it wont bump up on every small hill, this function returns the height the camera would really be on

please dont post stuff like that when you do not understand a thing...
 
Level 10
Joined
May 26, 2005
Messages
194
yeah, its a whole bunch of code, however i doubt theres a way of calculating it way faster

and where did i get these values from?

well ^^ SetCameraPosition(), then a small wait, so the camera can move to the right position, then GetCameraTargetPositionZ()
i visualized it with dummy units and tried to find rules. It seemed like the map was divided into squares, in which the camera height is interpolated. actually this was wrong, because there are smaller areas near the borders between two of those squares, which are calculated different, somehow... dont know why blizzard did that ^^
however, then i did the same measurement thing on a flat surface, then time after time raised single terrain heightmap pixels by a specific value and measured, how big the effect was on the camera Z i measured. those effect factors made up a grid following some principles. they turned out to be some weird average values on a 512x512 square, then combined with the 8 surrounding 512x512 squares.

testing and simplifying lead to this function. took me some time to figure it out anways, but i did not give up :p


basically:

cameramapInit() calculates the average height values for all 512x512 squares on the map.
in order to keep wc3 running on big maps, the loop is contained in another function:
cameramapInit_GridSub()


GetGridCamOffset() combines 9 of the saved height values to get another average which will later be used

GetCamOffset() interpolates the 4 corner heights around the given coordinates, giving the actual value at that position


in the beginning i did not even know whether i could find it out, and i was quite lucky that blizzard uses linear interpolation here, the easiest to detect. the original blizzard code probably looks different, maybe the priority of the the single height values is calculated by some formula depending on the distance from the center of the 512x512 square, however, i could not easily figure something like that out and this works perfectly.
 
Level 8
Joined
Apr 5, 2008
Messages
367
Could you explain again why it is better than the GetLocationZ() stuff?
Is it just smoother or rather for placing the right x/y coordinate for the camera?
Because for my map I use the GetLocationZ() stuff and have on set x/y camera adjustment. But since the distance to the unit never changes I needn't re-adjust them.
But it's just a Diablo-Map, thus less comparable to other 3rd Person things.
 
Level 10
Joined
May 26, 2005
Messages
194
the camera does not raise its height for every small hill, but creates an average of the terrain and saves it to a heightmap. this way you can set the camera height precisely.

(SetCamerField(CAMERA_FIELD_ZOFFSET, z-GetCamOffset(x,y))

dont know whether it would be useful for you...
 
Level 10
Joined
Sep 21, 2007
Messages
517
dude, nice man, so this calculates the correct CamOffset the cam should have? like what if i want the cam offset to look like its 100 on every piece of terrain? i can use this? man so helpful if so, iv been trying to find a formula for it...

so i can do z-GetCamOffset(x,y)+100?

btw for your flight stimulator, u use wc3campaigns dummy model to rotate the plane?
 
Level 10
Joined
Sep 21, 2007
Messages
517
so dude was my formula correct? btw about the model thing i thought it was a sfx using using grim1000s modified dummy from vexorian, by changing the "root" of the model to make it face a certain direction. Its pretty interesting ^^ and thanks about me being able to use ur model without giving credits, kind of u :p but not making any flight stimultor map or anything of the sort >_>
 
Level 4
Joined
May 17, 2005
Messages
94
May I inquire as to what advantage exactly this has over the Toadcop method?

JASS:
//Toadcop's Method:
function SetCameraZ takes real z returns nothing
    set z = GetCameraField(CAMERA_FIELD_ZOFFSET)+z-GetCameraTargetPositionZ()
    call SetCameraField(CAMERA_FIELD_ZOFFSET,z,- 0.01)
    call SetCameraField(CAMERA_FIELD_ZOFFSET,z,0.01)
endfunction
 
Level 8
Joined
Aug 6, 2008
Messages
451
Well, I havent tsted this method, so I dont know if it works more smoothly, but that Toadcops method aint that good.

At least Ive had some problems with it. It doesnt look good: it jerks weirdly sometimes and stuff like that. ( As far as I remember from my old tests )
 
Level 10
Joined
May 26, 2005
Messages
194
May I inquire as to what advantage exactly this has over the Toadcop method?

JASS:
//Toadcop's Method:
function SetCameraZ takes real z returns nothing
    set z = GetCameraField(CAMERA_FIELD_ZOFFSET)+z-GetCameraTargetPositionZ()
    call SetCameraField(CAMERA_FIELD_ZOFFSET,z,- 0.01)
    call SetCameraField(CAMERA_FIELD_ZOFFSET,z,0.01)
endfunction

this only works when the camera is already set to a specific location. You can use SetCameraZ when the camera is already refreshed, but if you use PanCameraTo instantly before it, then this wont work, as GetCameraTargetPositionZ() uses the current visible camera, and wc3 needs some time to apply changes to it (~0.01 seconds?)
in that case toadcops method would use the Z offset of the last camera position. for slow camera movement that could be okay.
but all in all... matter of taste maybe... mine works absolutely precise in a very specific situation. and thats what i needed
 
Level 8
Joined
Apr 5, 2008
Messages
367
I use the Toadscope method in my map and it works wonderful. However I got one question:
JASS:
//Toadcop's Method:
function SetCameraZ takes real z returns nothing
    set z = GetCameraField(CAMERA_FIELD_ZOFFSET)+z-GetCameraTargetPositionZ()
    call SetCameraField(CAMERA_FIELD_ZOFFSET,z,- 0.01) // Why is that done two times, once with a negative and once with a positive value? 
    call SetCameraField(CAMERA_FIELD_ZOFFSET,z,0.01)   // I ask because I thought it was just unnecessary performance loss 
endfunction
 
Level 8
Joined
Aug 6, 2008
Messages
451
Its just a bug of some sort.
Using negative duration value before positive value seems to be a way to fuck up blizzards stupid camera smoothning. And thats what the function is used for.
 
Level 10
Joined
May 26, 2005
Messages
194
I tried toadcops method in my map, and it really does about the same job...
But theres a difference: His method is not smooth. Sometimes the camera is at the wrong position, its not much, however, enough to be annoying in my case.

To provide a similiar method:

Code:
function SetCameraXYZ takes real x, real y, real z returns nothing
        call SetCameraField(CAMERA_FIELD_ZOFFSET,z-GetCamOffset(x,y),0)
        call PanCameraToTimed(x,y,0)
endfunction
 
Level 10
Joined
May 26, 2005
Messages
194
Nope, there's unfortunately no way to get the precise unitZ. It is common to use GetLocationZ + GetUnitFlyHeight, however this returns wrong values for flying units near cliffs and walking/hovering units in water (rare case).
I already found out that theres also some sort of grid for flying units, not very different from that used for camera smoothing, however, the calculation of the grid values is different. besides that it would be very annoying work to find the true grid calculation, because there is no way to get the true unitZ even with some tricky, time-consuming stuff. you would have to compare the fly heights of hovering vs flying units...

and still: ground units (walk + hover) walk on the terrain below water, while amphibious or swimming units walk on the water surface. flying units also use the water surface as a reference point (which is good, because this is what GetLocationZ returns)

however, all in all the difference between GetLocationZ+GetUnitFlyHeight compared to true value is never too big. I also use this approximation for my Supreme Commander map, it sometimes looks a bit weird near cliffs but is not very noticable in general.

EDIT: I forgot one important thing to mention - you can set a value for destructables for flying units to fly over them and not through them. the only (easy) way to fix this, is removing these values from all of your destructable. you could also save them all in some variables, calculate something like that grid i mentioned before, and then try to figure out their influence... however, not very clean nor fast nor necessary

and... let me guess, you are german?

EDIT2: Started to look into it again, but its even more annoying than what ive thought - flying units do not simply read one point from that grid, but about 4 and then choose the highest one (probably), this makes them fly on the same height for a short time on top of a hill

EDIT3: I am no longer sure about EDIT2, however, it is quite obvious that the grid cells have a size of 256x256 instead of 512x512 (what ive expected before)...
that means 4 times the values to be saved... this is quite a lot of data
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
Pulled out from the graveyard by user request.

Based on the comments this seems to be a working snippet
with lacking documentation and privatization. I didn't check and tried the content myself.
Currently this resource remains not approve-able due to know issues ( read comments )
I also doubt that the N-a-z-g-u-l will update his snippet.
You might want to improve the code and re-submit it in the JASS section.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Here is OP with privatization and relevant lib name:
GetCamOffset(x,y) is the only function to access from outside the library.
It returns the camera z offset on a given terrain position, useful for placing the camera correctly for 3rd person cams and so on...
however, does not work for destructables with an overfly-z-size, nor for water

for everything else, it works so precise that you wont see any inaccuracy with your eyes, i made a 3d flight simulator using it, and the cam sticks to the plane very well

Demo map:
http://www.hiveworkshop.com/forums/maps-564/flightsim-concept-131344/

JASS:
library GetCamOffset initializer cameramapInit
    globals
        private location cameramapLoc
        private real array camOffset[90][90]
        private real mapMinX
        private real mapMinY
        private real mapMaxX
        private real mapMaxY
    endglobals
    
    private function GetGridCamOffset takes integer ix, integer iy, integer offx, integer offy returns real
        local real r
        local integer ixl = ix-1
        local integer ixr = ix+1
        local integer iyd = iy-1
        local integer iyu = iy+1
        if ixl<0 then
            set ixl = 0
        endif
        if iyd<0 then
            set iyd = 0
        endif
        if ixr>256 then
            set ixr=256
        endif
        if iyu>256 then
            set iyu=256
        endif
        if offx>0 then
            if offy>0 then
                set r =   .089696*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .097349*camOffset[ixr][iyu]
                set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
                set r = r+.082587*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .082587*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
                set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
                set r = r+.089696*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .097349*camOffset[ixr][iyd]
            else
                set r =   .084604*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
                set r = r+.134017*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .142877*camOffset[ixr][iy]
                set r = r+.084604*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
            endif
        elseif offx<0 then
            if offy>0 then
                set r =   .097349*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
                set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
                set r = r+.089696*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .082587*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .089696*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .082587*camOffset[ixr][iyu]
                set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
                set r = r+.097349*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
            else
                set r =   .091913*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
                set r = r+.142877*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134017*camOffset[ixr][iy]
                set r = r+.091913*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
            endif
        else
            if offy>0 then
                set r =   .091913*camOffset[ixl][iyu]+ .142877*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
                set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]
                set r = r+.084604*camOffset[ixl][iyd]+ .134017*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .084604*camOffset[ixl][iyu]+ .134017*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
                set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]                
                set r = r+.091913*camOffset[ixl][iyd]+ .142877*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
            else
                set r =   .086125*camOffset[ixl][iyu]+ .136429*camOffset[ix][iyu]+ .086125*camOffset[ixr][iyu]
                set r = r+.136429*camOffset[ixl][iy] + .109784*camOffset[ix][iy] + .136429*camOffset[ixr][iy]
                set r = r+.086125*camOffset[ixl][iyd]+ .136429*camOffset[ix][iyd]+ .086125*camOffset[ixr][iyd]
            endif
        endif
        return r
    endfunction
    
    function GetCamOffset takes real x, real y returns real
        local integer iXLo = R2I((x-mapMinX)/512.+.5)
        local integer iYLo = R2I((y-mapMinY)/512.+.5)
        local integer iXHi = iXLo+1
        local integer iYHi = iYLo+1
        local integer iChkXLo
        local integer iChkXLoOff
        local integer iChkXHi
        local integer iChkXHiOff
        local integer iChkYLo
        local integer iChkYLoOff
        local integer iChkYHi
        local integer iChkYHiOff
        local real XLo
        local real YLo
        local real XHi
        local real YHi
        local real rX
        local real rY
        local real r
        local real LoDX = (x-mapMinX)-(iXLo*512.-256.)
        local real LoDY = (y-mapMinY)-(iYLo*512.-256.)
        if LoDX<=12 then
            set iChkXLo = iXLo
            set iChkXLoOff = 0
            set iChkXHi = iXLo
            set iChkXHiOff = 1
        elseif LoDX<500 then
            set iChkXLo = iXLo
            set iChkXLoOff = 1
            set iChkXHi = iXHi
            set iChkXHiOff =-1
        else
            set iChkXLo = iXHi
            set iChkXLoOff =-1
            set iChkXHi = iXHi
            set iChkXHiOff = 0
        endif
        if LoDY<=12 then
            set iChkYLo = iYLo
            set iChkYLoOff = 0
            set iChkYHi = iYLo
            set iChkYHiOff = 1
        elseif LoDY<500 then
            set iChkYLo = iYLo
            set iChkYLoOff = 1
            set iChkYHi = iYHi
            set iChkYHiOff =-1
        else
            set iChkYLo = iYHi
            set iChkYLoOff =-1
            set iChkYHi = iYHi
            set iChkYHiOff = 0
        endif
        set XLo = iChkXLo*512.+iChkXLoOff*12.-256.
        set XHi = iChkXHi*512.+iChkXHiOff*12.-256.
        set YLo = iChkYLo*512.+iChkYLoOff*12.-256.
        set YHi = iChkYHi*512.+iChkYHiOff*12.-256.
        set rX = ((x-mapMinX)-XLo)/(XHi-XLo)
        set rY = ((y-mapMinY)-YLo)/(YHi-YLo)
        set r =   GetGridCamOffset(iChkXHi,iChkYHi,iChkXHiOff,iChkYHiOff)*rX*rY
        set r = r+GetGridCamOffset(iChkXLo,iChkYHi,iChkXLoOff,iChkYHiOff)*(1-rX)*rY
        set r = r+GetGridCamOffset(iChkXHi,iChkYLo,iChkXHiOff,iChkYLoOff)*rX*(1-rY)
        set r = r+GetGridCamOffset(iChkXLo,iChkYLo,iChkXLoOff,iChkYLoOff)*(1-rX)*(1-rY)
        return r
    endfunction
    
    private function cameramapInit_GridSub takes real x, real y returns real
        local integer index
        local integer iX = -6
        local integer iY
        local real z
        local real r
        local real i = 64 //9*4+12*2+4
        call MoveLocation(cameramapLoc,x,y)
        set z = GetLocationZ(cameramapLoc)
        set r = 0.
        call MoveLocation(cameramapLoc,x-128.,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x-128.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x-128.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        
        call MoveLocation(cameramapLoc,x-256.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x-256.,y)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x-256.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x+256.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+256.,y)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+256.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x-128.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+128.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x-128.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+128.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        
        call MoveLocation(cameramapLoc,x+256.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x+256.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x-256.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x-256.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        return r
    endfunction
    
    private function cameramapInit_DoRow takes nothing returns nothing
        local real x = mapMinX+256.
        local real y = mapMinY+256.
        local integer iX = bj_forLoopAIndex
        local integer iY = 0
        loop
            exitwhen y+iY*512.>mapMaxY
            set camOffset[(iX+1)][iY+1] = cameramapInit_GridSub(x+iX*512.,y+iY*512.)
            set iY = iY + 1
        endloop
    endfunction

    private function cameramapInit takes nothing returns nothing
        local real x
        local real y
        local integer iX = 0
        local integer iY
        local rect map = GetWorldBounds()
        set mapMinX = GetRectMinX(map)
        set mapMinY = GetRectMinY(map)
        set mapMaxX = GetRectMaxX(map)
        set mapMaxY = GetRectMaxY(map)
        call RemoveRect(map)
        set map = null
        set x = mapMinX+256.
        set y = mapMinY+256.
        set cameramapLoc = Location(0,0)
        loop
            exitwhen x+iX*512.>mapMaxX
            set bj_forLoopAIndex = iX
            call ExecuteFunc("cameramapInit_DoRow")
            set iX = iX + 1
        endloop
        call RemoveLocation(cameramapLoc)
        set cameramapLoc = null
    endfunction
endlibrary

I can edit the op to match if others want it.
 
Level 5
Joined
Apr 26, 2006
Messages
160
I am so confused, how do you make this function in a map?

I tried downloading OP's map to just see how it worked there but it gives errors so it doesn't launch.

I'm able to get the library and launch my map but I don't really understand JASS well and I don't think there's anything calling this to function... But my experiments aren't doing anything either, and I'm not really sure where to go from here.
 
Last edited:
Level 9
Joined
Mar 6, 2012
Messages
64
I am so confused, how do you make this function in a map?

I tried downloading OP's map to just see how it worked there but it gives errors so it doesn't launch.

I'm able to get the library and launch my map but I don't really understand JASS well and I don't think there's anything calling this to function... But my experiments aren't doing anything either, and I'm not really sure where to go from here.
Use this instead. You only need to use the GetCamOffset function, which returns Warcraft's generated camera z-offset at a specific XY-coordinate. (For some reason, the one posted here doesnt return the right values)
vJASS:
library GetCamOffset initializer cameramapInit
    globals
        location cameramapLoc
        real array camOffset[256][256]
        real mapMinX
        real mapMinY
        real mapMaxX
        real mapMaxY
    endglobals
   
    function GetGridCamOffset takes integer ix, integer iy, integer offx, integer offy returns real
        local real r
        local integer ixl = ix-1
        local integer ixr = ix+1
        local integer iyd = iy-1
        local integer iyu = iy+1
        if ixl<0 then
            set ixl = 0
        endif
        if iyd<0 then
            set iyd = 0
        endif
        if ixr>256 then
            set ixr=256
        endif
        if iyu>256 then
            set iyu=256
        endif
        if offx>0 then
            if offy>0 then
                set r =   .089696*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .097349*camOffset[ixr][iyu]
                set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
                set r = r+.082587*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .082587*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
                set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
                set r = r+.089696*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .097349*camOffset[ixr][iyd]
            else
                set r =   .084604*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
                set r = r+.134017*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .142877*camOffset[ixr][iy]
                set r = r+.084604*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
            endif
        elseif offx<0 then
            if offy>0 then
                set r =   .097349*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
                set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
                set r = r+.089696*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .082587*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .089696*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .082587*camOffset[ixr][iyu]
                set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
                set r = r+.097349*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
            else
                set r =   .091913*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
                set r = r+.142877*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134017*camOffset[ixr][iy]
                set r = r+.091913*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
            endif
        else
            if offy>0 then
                set r =   .091913*camOffset[ixl][iyu]+ .142877*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
                set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]
                set r = r+.084604*camOffset[ixl][iyd]+ .134017*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
            elseif offy<0 then
                set r =   .084604*camOffset[ixl][iyu]+ .134017*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
                set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]               
                set r = r+.091913*camOffset[ixl][iyd]+ .142877*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
            else
                set r =   .086125*camOffset[ixl][iyu]+ .136429*camOffset[ix][iyu]+ .086125*camOffset[ixr][iyu]
                set r = r+.136429*camOffset[ixl][iy] + .109784*camOffset[ix][iy] + .136429*camOffset[ixr][iy]
                set r = r+.086125*camOffset[ixl][iyd]+ .136429*camOffset[ix][iyd]+ .086125*camOffset[ixr][iyd]
            endif
        endif
        return r
    endfunction
   
    function GetCamOffset takes real x, real y returns real
        local integer iXLo = R2I((x-mapMinX)/512.+.5)
        local integer iYLo = R2I((y-mapMinY)/512.+.5)
        local integer iXHi = iXLo+1
        local integer iYHi = iYLo+1
        local integer iChkXLo
        local integer iChkXLoOff
        local integer iChkXHi
        local integer iChkXHiOff
        local integer iChkYLo
        local integer iChkYLoOff
        local integer iChkYHi
        local integer iChkYHiOff
        local real XLo
        local real YLo
        local real XHi
        local real YHi
        local real rX
        local real rY
        local real r
        local real LoDX = (x-mapMinX)-(iXLo*512.-256.)
        local real LoDY = (y-mapMinY)-(iYLo*512.-256.)
        if LoDX<=12 then
            set iChkXLo = iXLo
            set iChkXLoOff = 0
            set iChkXHi = iXLo
            set iChkXHiOff = 1
        elseif LoDX<500 then
            set iChkXLo = iXLo
            set iChkXLoOff = 1
            set iChkXHi = iXHi
            set iChkXHiOff =-1
        else
            set iChkXLo = iXHi
            set iChkXLoOff =-1
            set iChkXHi = iXHi
            set iChkXHiOff = 0
        endif
        if LoDY<=12 then
            set iChkYLo = iYLo
            set iChkYLoOff = 0
            set iChkYHi = iYLo
            set iChkYHiOff = 1
        elseif LoDY<500 then
            set iChkYLo = iYLo
            set iChkYLoOff = 1
            set iChkYHi = iYHi
            set iChkYHiOff =-1
        else
            set iChkYLo = iYHi
            set iChkYLoOff =-1
            set iChkYHi = iYHi
            set iChkYHiOff = 0
        endif
        set XLo = iChkXLo*512.+iChkXLoOff*12.-256.
        set XHi = iChkXHi*512.+iChkXHiOff*12.-256.
        set YLo = iChkYLo*512.+iChkYLoOff*12.-256.
        set YHi = iChkYHi*512.+iChkYHiOff*12.-256.
        set rX = ((x-mapMinX)-XLo)/(XHi-XLo)
        set rY = ((y-mapMinY)-YLo)/(YHi-YLo)
        set r =   GetGridCamOffset(iChkXHi,iChkYHi,iChkXHiOff,iChkYHiOff)*rX*rY
        set r = r+GetGridCamOffset(iChkXLo,iChkYHi,iChkXLoOff,iChkYHiOff)*(1-rX)*rY
        set r = r+GetGridCamOffset(iChkXHi,iChkYLo,iChkXHiOff,iChkYLoOff)*rX*(1-rY)
        set r = r+GetGridCamOffset(iChkXLo,iChkYLo,iChkXLoOff,iChkYLoOff)*(1-rX)*(1-rY)
        return r
    endfunction
   
    function cameramapInit_GridSub takes nothing returns nothing
        local integer index
        local integer iX = -6
        local integer iY
        local real z
        local real r
        local real x = bj_cineFadeContinueRed
        local real y = bj_cineFadeContinueBlue
        local real i = 64 //9*4+12*2+4
        call MoveLocation(cameramapLoc,x,y)
        set z = GetLocationZ(cameramapLoc)
        set r = 0.
        call MoveLocation(cameramapLoc,x-128.,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x-128.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x-128.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
        call MoveLocation(cameramapLoc,x+128.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*4./i
       
        call MoveLocation(cameramapLoc,x-256.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x-256.,y)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x-256.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
       
        call MoveLocation(cameramapLoc,x+256.,y-128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+256.,y)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+256.,y+128.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
       
        call MoveLocation(cameramapLoc,x-128.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+128.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
       
        call MoveLocation(cameramapLoc,x-128.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
        call MoveLocation(cameramapLoc,x+128.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*2./i
       
        call MoveLocation(cameramapLoc,x+256.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x+256.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x-256.,y+256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        call MoveLocation(cameramapLoc,x-256.,y-256.)
        set r = r+GetLocationZ(cameramapLoc)*1./i
        set bj_cineFadeContinueGreen = r
    endfunction

    function cameramapInit takes nothing returns nothing
        local real x
        local real y
        local integer iX = 0
        local integer iY
        local rect map = GetWorldBounds()
        set mapMinX = GetRectMinX(map)
        set mapMinY = GetRectMinY(map)
        set mapMaxX = GetRectMaxX(map)
        set mapMaxY = GetRectMaxY(map)
        call RemoveRect(map)
        set map = null
        set x = mapMinX+256.
        set y = mapMinY+256.
        set cameramapLoc = Location(0,0)
        loop
            exitwhen x+iX*512.>mapMaxX
            set iY = 0
            loop
                exitwhen y+iY*512.>mapMaxY
                set bj_cineFadeContinueRed = x+iX*512.
                set bj_cineFadeContinueBlue = y+iY*512.
                call ExecuteFunc("cameramapInit_GridSub")
                set camOffset[(iX+1)][iY+1] = bj_cineFadeContinueGreen
                set iY = iY + 1
            endloop
            set iX = iX + 1
        endloop
        call RemoveLocation(cameramapLoc)
        set cameramapLoc = null
    endfunction
endlibrary
 
Top