@name Holo-arm
@inputs 
@outputs 
@persist T:vector [Delta Joints Mins]:array Hand:entity
@persist [Ang Mod Par Pos Sca]:array HC Base:vector
@trigger 

if(first()){
    Base=entity():pos()+entity():up()*45
    F=entity():forward() For=F:toAngle()+ang(90,0,0) HC=1
    Ang=array() Mod=array()   Par=array() Pos=array() Sca=array()
    Ang:pushAngle(ang()) Ang:pushAngle(ang()) Ang:pushAngle(For) Ang:pushAngle(ang()) Ang:pushAngle(For) Ang:pushAngle(ang())
    Mod:pushString("hqicosphere2") Mod:pushString("hqicosphere2") Mod:pushString("hqcylinder") Mod:pushString("hqicosphere2") Mod:pushString("hqcylinder") Mod:pushString("")
    Par:pushNumber(1) Par:pushNumber(1) Par:pushNumber(1) Par:pushNumber(2) Par:pushNumber(2) Par:pushNumber(4)
    Pos:pushVector(vec()) Pos:pushVector(F*30) Pos:pushVector(F*15) Pos:pushVector(F*60) Pos:pushVector(F*45) Pos:pushVector(F*70)
    Sca:pushVector(vec(1,1,1)) Sca:pushVector(vec(1,1,1)) Sca:pushVector(vec(1,1,2)) Sca:pushVector(vec(1,1,1)) Sca:pushVector(vec(1,1,2)) Sca:pushVector(vec(1,1,1/2))
}
if(HC<Pos:count()){
    interval(1000)
}
else{
    if(!Joints[1,number]|!Hand){
        Hand=holoEntity(6)
        
            #Indexes of Joint holos
        Joints:pushNumber(1)
        Joints:pushNumber(2)
        Joints:pushNumber(4)
    }
    runOnTick(1)
}

#Holo arm generation
M=0
while(HC<=Pos:count() & M<=10){
    A=Ang[HC,angle]
    Mo=Mod[HC,string]
    Pa=Par[HC,number]
    Po=Pos[HC,vector]
    Sc=Sca[HC,vector]
    
    holoCreate(HC,Po+Base,Sc,A)
    holoModel(HC,Mo)
    holoParent(HC,Pa)
    
    HC++,M++
}

if(tickClk()){
    T=owner():aimPos()
    
    if(Hand:pos():distance(T)>=5){
        M=0
        while(M<=Joints:count()){
            J=holoEntity(Joints[M,number]) #Joint to check
            Cl=1 #Per execution clamp of rotation
                        
            Sho=((T-J:pos()):toAngle()) #Aim angle
                Sha=angnorm(J:angles()) #Current angle
                Sd=angnorm(Sho-Sha):setRoll(0) #Delta of angle
                
                #Scale
            S=abs(Sd:pitch())+abs(Sd:yaw())+abs(Sd:roll())
                Mins:pushNumber((S ? S : Cl*4))
                
                        #Angular components
                    Sp=Sd:pitch() Sy=Sd:yaw() Sr=Sd:roll()
                    P=(abs(Sp)>=Cl ? Cl*sign(Sp) : Sp)
                    Y=(abs(Sy)>=Cl ? Cl*sign(Sy) : Sy)
                    R=(abs(Sr)>=Cl ? Cl*sign(Sr) : Sr)
            
                #Normalized delta
            Sd=ang(P,Y,R)
                Delta:pushAngle(Sd)
                
            M++
        }
        if(M>=Joints:count()){
                #Joint holo index with the smallest delta
            Hol=Joints[Mins:minIndex(),number]
            
            J=holoEntity(Hol) #Joint holo
            Jdel=Delta[Hol,angle] #Angle addition
            
            holoAng(Hol,J:angles()+Jdel)
            
            #Emptying arrays
            Mins=array()
            Delta=array()
                #I'm not sure why but for some reason
                #the motion is really buggy without persisting
                #of these temporary arrays
        }
    }
}
