@name Networked Hologram 14-seg
@inputs In:string Scale Masterent:entity
@persist ID Defaultpos:array Chardefs:table
@persist OldChar:string OldScale OldFrame:matrix OldOrigin:vector
#Grouping, colour variables
gSetGroup("14-segs")
Oncol=vec4(255,255,255,255)
Offcol=vec4(0,0,0,0)

#Startup: self-identification, hologram creation
#Setting up definition tables
if(first()) {
    runOnTick(1)
    ID = gGetNum("Indicators")+1
    gSetNum("Indicators",ID)    
    #gDeleteAll()
    Index=(ID-1)*14+1
    Material="models/shiny"
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    holoCreate(Index) holoMaterial(Index,Material) Index++
    
    #Local definitions for positions, directions and scales of different segments
    Hscale=vec(2,0.25,0.25)
    Half=vec(Hscale:x()/2,0.25,0.25)
    Small=vec(2.1,0.2,0.2)
    Angle=67.5
    Temp=matrix(vec(0,0,4),vec(0,1,0),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,1,3),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,1,1),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0,0),vec(0,1,0),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-1,1),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-1,3),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-0.5,2),vec(0,1,0),Half)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0.5,2),vec(0,1,0),Half)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0,1),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0,3),vec(0,0,1),Hscale)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-0.5,3),vec(0,cos(Angle),-sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0.5,3),vec(0,cos(Angle),sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,-0.5,1),vec(0,cos(Angle),sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    Temp=matrix(vec(0,0.5,1),vec(0,cos(Angle),-sin(Angle)),Small)
    Defaultpos:pushMatrix(Temp)
    
    #Character definitions
    #Characters follow the ABCDEF of the Wire 7-seg indicator
    #Each character's definition is indexed by the character itself
    Chardefs:setString("0","11111100000000")
    Chardefs:setString("1","01100000000000")
    Chardefs:setString("2","11011011000000")
    Chardefs:setString("3","11110011000000")
    Chardefs:setString("4","01100111000000")
    Chardefs:setString("5","10110111000000")
    Chardefs:setString("6","10111111000000")
    Chardefs:setString("7","11100000000000")
    Chardefs:setString("8","11111111000000")
    Chardefs:setString("9","11110111000000")
    Chardefs:setString("A","11101111000000")
    Chardefs:setString("B","11111111000000")
    Chardefs:setString("C","10011100000000")
    Chardefs:setString("D","11111100000000")
    Chardefs:setString("E","10011111000000")
    Chardefs:setString("F","10001111000000")
    Chardefs:setString("G","10111101000000")
    Chardefs:setString("H","01101111000000")
    Chardefs:setString("I","01100000000000")
    Chardefs:setString("J","01111000000000")
    Chardefs:setString("K","00001110000101") 
    Chardefs:setString("L","00011100000000")
    Chardefs:setString("M","01101100001100") 
    Chardefs:setString("N","01101100001001") 
    Chardefs:setString("O","11111100000000")
    Chardefs:setString("P","11001111000000")
    Chardefs:setString("Q","11111100000001")
    Chardefs:setString("R","11001111000001")
    Chardefs:setString("S","10110111000000")
    Chardefs:setString("T","10000000110000")
    Chardefs:setString("U","01111100000000")
    Chardefs:setString("V","00001100000110") 
    Chardefs:setString("W","01101100000011") 
    Chardefs:setString("X","00000000001111") 
    Chardefs:setString("Y","00000000101100")
    Chardefs:setString("Z","10010000000110")
    Chardefs:setString(" ","00000000000000") 
    Chardefs:setString("-","00000011000000")
    
    
    exit()
    }

#If this is the input chip, set it to master and
#transfer the input to others.
if(~In|~Masterent|~Scale){
    gSetStr("Display",In:upper())#Only uppercase
    Master = ( Masterent ? Masterent : entity() )
    gSetEnt("Master",Master)
    gSetNum("Scale",Scale)
    }

#Identify the character to display
Char = gGetStr("Display"):index(ID)
Scale = gGetNum("Scale")
if(Char==""|!Scale){
    Index = (ID-1)*7+1
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    holoColor(Index,vec(),0) Index++
    exit()}

#Move holos to position, scale them
#Now only triggers if there has been change in position or scale.
Master = gGetEnt("Master")
Frame = matrix(Master)*Scale
Origin = Master:toWorld(vec(0,3*(ID-1),5)*Scale)
Index = (ID-1)*14+1
Indicator=1
Roll = Master:forward():toAngle():pitch()
if(Scale!=OldScale|Frame!=OldFrame|Origin!=OldOrigin){
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++

    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
    
    Matrix = Defaultpos:matrix(Indicator)
    holoPos(Index,Origin + Frame*Matrix:column(1))
    holoAng(Index,(Frame*Matrix:column(2)):toAngle():setRoll(Roll))
    if(Scale!=OldScale){holoScaleUnits(Index,Scale*Matrix:column(3))}
    Index++ Indicator++
}
OldScale=Scale OldFrame=Frame OldOrigin=Origin
    
#Recolor, if there has been change in the character to display
if(OldChar==Char){exit()} OldChar=Char
Index = (ID-1)*14+1
Indicator=1
Decoded = Chardefs:string(Char)

    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
        
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
        
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
    
    Col = (Decoded:index(Indicator):toNumber() ? Oncol : Offcol)
    holoColor(Index,vec(Col),Col:w())
    Index++ Indicator++
