Terrain (physics/normal system) struct leaking problem

Prozix

New Member
Reaction score
7
my code

JASS:
library ExtraPhysicsFunctions
function GetTerrainZ  takes real x, real y returns real z
    local unit u = CreateUnit(Player(12),'hnth', x, y, 0)
    local location l = GetUnitLoc(u)
    local real r = GetLocationZ(l)
    call RemoveLocation(l)
    call RemoveUnit(u)
    return r
endfunction
endlibrary

JASS:
library Physics initializer Init requires ExtraPhysicsFunctions
//--------------------------------------------------------
globals
    private constant real STANDARD_MASS = 10.0
    private constant real GRAVITY_ACCELERATION = 9.81
    private constant real FRICTION = 0.98
    
    private constant integer ORDER_RIGHT_CLICK = 851971
    private constant integer ORDER_MOVE = 851986
    private constant integer ORDER_ATTACK_MOVE = 851983
endglobals
//--------------------------------------------------------
function IsMoveOrder takes integer order returns boolean
    return order==ORDER_RIGHT_CLICK or order==ORDER_MOVE or order==ORDER_ATTACK_MOVE
endfunction

struct vec
    real x
    real y
    real z
    static method Create takes nothing returns vec
        local vec v = vec.allocate()
        call v.SetXYZ(0,0,0)
        return v
    endmethod
    //SET-------------------------------------
    method SetByVec takes vec v returns nothing
        set .x = v.x
        set .y = v.y
        set .z = v.z
    endmethod
    method SetXYAutoZ takes real x, real y returns nothing
        set .x = x
        set .y = y
        set .z = GetTerrainZ(x, y)
    endmethod
    method SetXYZ takes real x, real y, real z returns nothing
        set .x = x
        set .y = y
        set .z = z
    endmethod
    //OPERATORS-------------------------------------
    method Add takes vec v returns nothing
        set .x = .x + v.x
        set .y = .y + v.y
        set .z = .z + v.z
    endmethod
    method Substract takes vec v returns nothing
        set .x = .x - v.x
        set .y = .y - v.y
        set .z = .z - v.z
    endmethod
    method MultiplyByVec takes vec v returns nothing
        set .x = .x * v.x
        set .y = .y * v.y
        set .z = .z * v.z
    endmethod
    method MultiplyByReal takes real r returns nothing
        set .x = .x * r
        set .y = .y * r
        set .z = .z * r
    endmethod
    //MISC--------------------------------------------
    static method CrossProduct takes vec v1, vec v2 returns vec
        local vec v = vec.create()
        call v.SetXYZ((v1.y*v2.z - v1.z*v2.y), (v1.z*v2.x - v1.x*v2.z), (v1.x*v2.y - v1.y*v2.x))
        return v
    endmethod
    method Print takes nothing returns nothing
        call BJDebugMsg("vec(" + R2S(.x) + "; " + R2S(.y) + "; " + R2S(.z) + ")")
    endmethod
    method AngleWithXY takes nothing returns real
        local real alpha
        local real ANS
        //calculate alpha
        set ANS = SquareRoot(.x*.x + .y*.y)
        if ANS == 0.0 then
            set alpha = bj_PI/2
        else
            set alpha = Atan(.z/ANS)
        endif
        return alpha
    endmethod
    method Size takes nothing returns real
        return SquareRoot(.x*.x + .y*.y + .z*.z)
    endmethod
endstruct

globals
    vec uVel
endglobals
//--------------------------------------------------------
private function Update takes nothing returns nothing
    local unit u = gg_unit_Hblm_0001
    
    local real alpha = 0.0 //angle between surface and z=0
    
    local real oX = GetUnitX(u)
    local real oY = GetUnitY(u)
    local real Fz = STANDARD_MASS * GRAVITY_ACCELERATION
    
    //points
    local vec p1 = vec.Create()
    local vec p2 = vec.Create()
    local vec p3 = vec.Create()
    //face vectors
    local vec v1 = vec.Create()
    local vec v2 = vec.Create()
    //normal
    local vec n
    local vec a = vec.Create()
    
    //START doing things
    call p1.SetXYAutoZ(oX + 10, oY)
    call p2.SetXYAutoZ(oX - 8, oY+6)
    call p3.SetXYAutoZ(oX - 8, oY-6)

    call v1.SetXYZ(p2.x-p1.x, p2.y-p1.y, p2.z-p1.z)
    call v2.SetXYZ(p3.x-p1.x, p3.y-p1.y, p3.z-p1.z)
    
    set n = vec.CrossProduct(v1, v2) //point perpendicular to v1 and v2
    
    set alpha = bj_PI/2 - n.AngleWithXY() //2PI(triangle)-PI/2-angle of the normal = angle of the surface with z=0
    
    call a.SetByVec(n)
    call a.MultiplyByReal(Fz*Cos(alpha)/n.Size())
    
    //call a.Print()
    
    call uVel.Add(a)
    call uVel.MultiplyByReal(FRICTION)
    
    if IsMoveOrder(GetUnitCurrentOrder(u)) or uVel.Size() < 1 then
        call uVel.SetXYZ(0,0,0)
    else
        set oX = oX+uVel.x/20
        set oY = oY+uVel.y/20
        //map bounds. can be done better, this is a temporary solution
        if oX > GetRectMaxX(bj_mapInitialPlayableArea)-64 then
            set oX = GetRectMaxX(bj_mapInitialPlayableArea)-64
            if  uVel.x > 0 then
                set uVel.x = -uVel.x
            endif
        elseif oX < GetRectMinX(bj_mapInitialPlayableArea)+64 then
            set oX = GetRectMinX(bj_mapInitialPlayableArea)+64
            if  uVel.x < 0 then
                set uVel.x = -uVel.x
            endif
        endif
        if oY > GetRectMaxY(bj_mapInitialPlayableArea)-64 then
            set oY = GetRectMaxY(bj_mapInitialPlayableArea)-64
            if  uVel.y > 0 then
                set uVel.y = -uVel.y
            endif
        elseif oY < GetRectMinY(bj_mapInitialPlayableArea)+64 then
            set oY = GetRectMinY(bj_mapInitialPlayableArea)+64
            if  uVel.y < 0 then
                set uVel.y = -uVel.y
            endif
        endif
        call SetUnitX(u, oX)
        call SetUnitY(u, oY)
        call SetUnitFacing(u, Rad2Deg(Atan2(uVel.y,uVel.x)))
    endif
    
    //cleanup
    call p1.destroy()
    call p2.destroy()
    call p3.destroy()
    
    call v1.destroy()
    call v2.destroy()
    
    call n.destroy()
    call a.destroy()
endfunction
//--------------------------------------------------------
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterTimerEvent(t, 0.03, true)
    call TriggerAddAction(t, function Update)
    
    set uVel = vec.Create()
endfunction
endlibrary
 

aliminator8

New Member
Reaction score
3
(I used your GetTerrainZ function but I used a locust, invunerable, no model, collision size=1, flying, unit to get the Z. It is way more. accurate because it doesn't get displaced. )

Lol great idea. I didn't even think of doing that ;p ,im gonna use that in my map straight away lol...
 

Prozix

New Member
Reaction score
7
the locals are not nulled. Here is a fix which can improve the code's efficiency greatly.
I didn't know a location would take the proper Z coodinate if is moved :O if this works it would be a great improvement indeed.
Do locals require to be nulled even if you are sure you don't use the variables after you have removed/deleted the object it points to?

Lol great idea. I didn't even think of doing that ;p ,im gonna use that in my map straight away lol...
If kingkings code works, you should defenitely use that instead of a unit and everything
 

Prozix

New Member
Reaction score
7
Here's my updated map, with some ingame commands and the code.
 

Attachments

  • Physics0.1.w3x
    37.8 KB · Views: 232
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top