Code:
@name Holographic Interface
@outputs JoystickValue:vector2 SliderValue Toggle
@persist [Pod Slider SliderHead Field Joystick Button]:entity
#########################################################
################# Holographic Interface #################
################# By Feha #################
#########################################################
##### Line-Point intersection explanation at bottom #####
#########################################################
if (first() | duped()) {
runOnTick(1)
Pod = entity():isWeldedTo()
#Create the base field
holoCreate(1)
holoScaleUnits(1,vec(1,55,48))
holoPos(1,Pod:toWorld(vec(0,50,25)))
holoAng(1,Pod:toWorld(ang(25,90,0)))
holoMaterial(1,"models/props_lab/tank_glass001")
holoParent(1,Pod)
Base = holoEntity(1)
#Create arrays over all the other holos
SpawnModel = array("","","hqcylinder","dome","dome")
SpawnScale = array(vec(1,2,30),vec(2,10,5),vec(30,30,1),vec(8,8,5),vec(10,10,5))
SpawnPos = array(vec(-2,-20,-5),vec(-2,-20,-5),vec(-2,10,-7),vec(-2,10,-7),vec(-2,-8,16))
SpawnAng = array(ang(0,0,0),ang(0,0,0),ang(90,0,0),ang(-90,0,0),ang(-90,0,0))
SpawnMaterial = array("models/props_lab/tank_glass001_dx60","models/props_lab/xencrystal_sheet","models/props_lab/tank_glass001_dx60","models/props_lab/xencrystal_sheet","spacebuild/fusion")
#Loop the arrays and create them local to the holo base field
for (I=2,6) {
holoCreate(I)
holoModel(I,SpawnModel[I-1,string])
holoScaleUnits(I,SpawnScale[I-1,vector]*1.04) #I heard this mult fixes holoScaleUnits()
holoPos(I,Base:toWorld(SpawnPos[I-1,vector]))
holoAng(I,Base:toWorld(SpawnAng[I-1,angle]))
holoMaterial(I,SpawnMaterial[I-1,string])
holoParent(I,1)
}
#The slider entities
Slider = holoEntity(2)
SliderHead = holoEntity(3)
#The joystick entities
Field = holoEntity(4)
Joystick = holoEntity(5)
#The button entity
Button = holoEntity(6)
}
#Stuff
Driver = Pod:driver()
LMB = Driver:keyAttack1()
Origin = Driver:shootPos()
OriginDirVec = Driver:eye()
################################
######## Button ##########
################################
ButtonPos = Button:pos()
Plane = ButtonPos
P1 = Origin
P2 = Origin+OriginDirVec
N = Button:up()
U = (N:dot(Plane-P1))/(N:dot(P2-P1))
Vec = P1+U*(P2-P1)
Aim = Vec:distance(ButtonPos) < 5 #Do you aim less then 5 units away from the button center?
if (Aim & changed(LMB) & LMB) {
Toggle = !Toggle
holoMaterial(6,"spacebuild/fusion"+toString(3*Toggle):replace("0",""))
}
################################
######## Slider ##########
################################
SliderPos = Slider:pos()
Plane = SliderPos
P1 = Origin
P2 = Origin+OriginDirVec
N = Slider:forward()
U = (N:dot(Plane-P1))/(N:dot(P2-P1))
Vec = P1+U*(P2-P1)
Dir = Slider:toLocal(Vec) #Where on sliders local Z axis do you aim
Aim = inrange(Dir:y(),-5,5) #Do you aim within the sliders width?
if (Aim & LMB) {
#The code I used before I checked up on line-plane intersection math.
# Vec = Driver:eye()*Origin:distance(SliderHead:pos())+Origin
# DirZ = SliderHead:toLocal(Vec):z()
# Z = Vec:distance(SliderHead:pos())*(DirZ/abs(DirZ))
# Vec = SliderHead:toWorld(vec(0,0,Z))
Vec = Slider:toWorld(vec(0,0,Dir:z())) #Turn the local Z into world?
Dist = Vec:distance(SliderPos)
if (Dist < 15) {
holoPos(3,Vec)
} else {
holoPos(3,SliderPos+(Vec-SliderPos):normalized()*15) #Set slider heap at top/bottom if you aim to far up/down on slider
}
}
#Get the slider value
DirZ = (Slider:toLocal(SliderHead:pos())):z() #Get the local Z
Dist = SliderHead:pos():distance(SliderPos)*(DirZ/abs(DirZ)) #Turn it into a distance (which can be negative)
if (abs(Dist) > 3) { #Is it more than 3 units from sliders center (to make setting stuff 0 easyer)?
SliderValue = (Dist/15) #Turn distance to a value ranging from -1 to 1
} else {
SliderValue = 0 #Otherwise make it 0
}
################################
######## Joystick ##########
################################
FieldPos = Field:pos()
Plane = FieldPos
P1 = Origin
P2 = Origin+OriginDirVec
N = Field:up()
U = (N:dot(Plane-P1))/(N:dot(P2-P1))
Vec = P1+U*(P2-P1)
Aim = Vec:distance(FieldPos) < 22 #Do you aim less then 22 units away from the joystick center?
#Bigger field to let you ctrl joystick even when not aiming at field (easyer getting max value).
if (Aim & LMB) {
#The code I used before I checked up on line-plane intersection math.
# Vec = Driver:eye()*Origin:distance(Joystick:pos())+Origin
# Dir = Joystick:toLocal(Vec)
# DirY = Dir:y()
# DirZ = Dir:z()
# Y = Vec:distance(Joystick:pos())*(DirY/abs(DirY))
# Z = Vec:distance(Joystick:pos())*(DirZ/abs(DirZ))
# Vec = Joystick:toWorld(vec(Z,Y,0))
Dist = Vec:distance(FieldPos)
if (Dist < 14) { #Do you aim less then 14 units away from the joystick center?
holoPos(5,Vec) #Position the joystick where you aim
} else { #Otherwise make it at edge of field, but towards where you aim
Vec = FieldPos+(Vec-FieldPos):normalized()*14
holoPos(5,Vec)
}
} else {
holoPos(5,FieldPos) #Snap back joystick to 0 when you stop hold it or aim to far away
}
#Get the joysticks value (vector2)
Dir = -Field:toLocal(Joystick:pos())/14 #Get where joystick is locally to field and make it into a value ranging from -1 to 1
JoystickValue = vec2(Dir:y(),Dir:x()) #Turn it into a vector2
#How does line-plane intersection work?
#Plane = HoloPos #Get the planes center
#P1 = Origin #Get a point on the line
#P2 = Origin+OriginDirVec #Get a point on the line "after" point 1
#N = Holo:up() #Get the normal (a vector pointin straight out of the surface) of the plane
#U = (N:dot(Plane-P1))/(N:dot(P2-P1)) #Not really sure how, but it returns how many times the distance from point 1 to point 2 you need to go from point 1 to reach the intersection
#Vec = P1+U*(P2-P1) #Get the intersections position
Bookmarks