Plugins mamagement

This commit is contained in:
nrhck 2019-03-10 23:06:04 +01:00
parent 9ecee93b43
commit c27151ec62
38 changed files with 3934 additions and 550 deletions

19
LJ.conf
View File

@ -1,13 +1,13 @@
[General]
lasernumber = 1
debug = 0
debug = 1
ljayserverip = 127.0.0.1
nozoscip = 127.0.0.1
bhoroscip = 127.0.0.1
[laser0]
color = -1
ip = 127.0.0.1
ip = 192.168.1.3
kpps = 25000
centerx = -1610
centery = 0
@ -26,7 +26,7 @@ warpdest = [[-1500., 1500.],
[laser1]
color = -1
ip = 192.168.1.3
ip = 127.0.0.1
kpps = 25000
centerx = 506
centery = 413
@ -81,3 +81,16 @@ warpdest = [[-1500., 1500.],
[ 1500.,-1500.],
[-1500.,-1500.]]
[plugins]
plugins = {
"nozoid": {"OSC": 8003, "command": ""},
"glyph": {"OSC": 8004, "command": "python3 plugins/laserglyph.py"},
"planet": {"OSC": 8005, "command": "python3 plugins/planetarium/main.py"},
"words": {"OSC": 8006, "command": "python3 plugins/livewords.py"},
"cycl": {"OSC": 8007, "command": "python3 plugins/textcycl.py"},
"simu": {"OSC": 8008, "command": "python plugins/simu.py"},
"bank0": {"OSC": 8010, "command": "python3 plugins/VJing/bank0.py"},
"ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py"},
"laserwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py"}
}

View File

@ -1,4 +1,4 @@
LJ v0.7.1
LJ v0.8.1
By Sam Neurohack, Loloster, Cocoa
@ -36,6 +36,7 @@ LJ supports Linux and OS X. Windows is unkown but welcome, if someone want to ju
#
# Install
#
@ -86,7 +87,7 @@ Check in your client code if the laser server IP is the good one
Run your client
to monitor redis server :
to monitor redis server, there is app for that or :
redis-cli monitor
@ -110,9 +111,21 @@ to monitor redis server :
redis-cli -h redisserverIP monitor
#
# Plugins
#
LJ comes with different plugins :
- LiveWords : Fill the input form and it's displayed. One word / laser.
- Textcycl : Cycle some words with adjustable length on one laser.
- Anaglyph : A green/red rotating cube. Try it with green/red 3D glasses !
- Planetarium : A 4 lasers planetarium.
- LaserPong : Our laser Pong is back !
#
# Program your own "Client"
# Program your own "Plugin"
#
@ -122,7 +135,12 @@ The server approach is based on redis, so you write and run your laser client so
- There is a clients folders with examples in different languages.
- Generate at least one point list array (say a square).
- Feed your point list array in string format to redis server.
-
- Tell LJ.conf your plugin configuration : OSC port and command line to start it.
#
# Nannou etherdeam simulator
#
#

6
cli.py
View File

@ -25,7 +25,7 @@ def handle():
argsparser = argparse.ArgumentParser(description="LJ v0.8")
argsparser.add_argument("-r","--redisIP",help="IP address to bind builtin servers (OSC and websocket) also must be the Redis server IP ",type=str)
argsparser.add_argument("-L","--Lasers",help="Number of lasers connected.",type=int)
argsparser.add_argument("-v","--verbose",help="Debug mode 0,1 or 2.",type=int)
argsparser.add_argument("-v","--verbose",help="Debug mode 0,1 or 2 (0 by default)",type=int)
argsparser.add_argument("-x","--invx",help="Invert laser 0 X axis again",action="store_true")
argsparser.add_argument("-y","--invy",help="Invert laser 0 Y axis again",action="store_true")
argsparser.add_argument("-d","--display",help="Point List number displayed in simulator",type=int)
@ -47,6 +47,8 @@ def handle():
if args.verbose != None:
#print "setting gstt.debug to", args.verbose
gstt.debug = args.verbose
else:
gstt.debug = 0
# Ports arguments
if args.iport:
@ -62,7 +64,7 @@ def handle():
oport = gstt.oport
if gstt.debug > 0:
print "gstt.oport:",gstt.oport
print "Accept OSC on port",gstt.oport
print "gstt.iport:",gstt.iport

View File

@ -10,17 +10,25 @@ LICENCE : CC
'''
import redis
import lj
import lj3
import math
import time
import argparse
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
#from osc4py3 import oscmethod as osm
from osc4py3.oscmethod import *
OSCinPort = 8004
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Text Cycling for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int)
argsparser.add_argument("-v","--verbose",help="Verbosity level (0 by default)",type=int)
args = argsparser.parse_args()
@ -41,7 +49,14 @@ if args.redisIP != None:
else:
redisIP = '127.0.0.1'
lj.Config(redisIP,ljclient)
if args.verbose:
debug = args.verbose
else:
debug = 0
lj3.Config(redisIP,ljclient)
width = 800
@ -94,6 +109,13 @@ def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
def OSCljclient(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /glyph/ljclient with value", value)
ljclient = value
lj3.LjClient(ljclient)
def Proj(x,y,z,angleX,angleY,angleZ):
rad = angleX * math.pi / 180
@ -130,58 +152,82 @@ def Run():
Left = []
Right = []
counter =0
WebStatus("LaserGlyph")
while 1:
# OSC Server callbacks
print("Starting OSC at 127.0.0.1 port",OSCinPort,"...")
osc_startup()
osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/ping*", lj3.OSCping)
osc_method("/glyph/ljclient", OSCljclient)
Left = []
Right = []
try:
x = vertices[0][0]
y = vertices[0][1]
z = vertices[0][2]
while 1:
Left = []
Right = []
x = vertices[0][0]
y = vertices[0][1]
z = vertices[0][2]
# The cube start always with vertice 0
# LJ tracers will "move" the laser to this first point in black, then move to the next with second point color.
# For more accuracy in dac emulator, repeat this first point.
# Cube Y axis rotation of 'counter' angle and 3d-2d Proj function.
#Left.append( Proj(x+LeftShift(z*5),y,z,0,counter,0))
#Right.append(Proj(x+RightShift(z*5),y,z,0,counter,0))
# Add all the cube points face by face.
for fa in faces:
for point in fa:
x = vertices[point][0]
y = vertices[point][1]
z = vertices[point][2]
Left.append(Proj(x+LeftShift(z*25),y,z,0,counter,0))
Right.append(Proj(x+RightShift(z*25),y,z,0,counter,0))
# Drawing step, 2 possibilities
# Red and Green drawn by laser 0
lj3.PolyLineOneColor(Left, c = red, PL = 0, closed = True)
lj3.PolyLineOneColor(Right, c = green, PL = 0, closed = True)
lj3.DrawPL(0)
'''
# Red on laser 1 and green on laser 2
lj3.PolyLineOneColor(Left, c = red, PL = 1, closed = True)
lj3.PolyLineOneColor(Right, c = green, PL = 2, closed = True)
lj3.DrawPL(1)
lj3.DrawPL(2)
'''
time.sleep(0.1)
counter += 1
if counter >360:
counter =0
# The cube start always with vertice 0
# LJ tracers will "move" the laser to this first point in black, then move to the next with second point color.
# For more accuracy in dac emulator, repeat this first point.
except KeyboardInterrupt:
pass
# Cube Y axis rotation of 'counter' angle and 3d-2d Proj function.
#Left.append( Proj(x+LeftShift(z*5),y,z,0,counter,0))
#Right.append(Proj(x+RightShift(z*5),y,z,0,counter,0))
# Gently stop on CTRL C
finally:
# Add all the cube points face by face.
for fa in faces:
for point in fa:
x = vertices[point][0]
y = vertices[point][1]
z = vertices[point][2]
WebStatus("Glyph Exit")
print("Stopping OSC...")
lj3.OSCstop()
pass
Left.append( Proj(x+LeftShift(z*25),y,z,0,counter,0))
Right.append(Proj(x+RightShift(z*25),y,z,0,counter,0))
print ("LaserGlyph Stopped.")
# Drawing step, 2 possibilities
# Red and Green drawn by laser 0
lj.PolyLineOneColor(Left, c = red, PL = 0, closed = True)
lj.PolyLineOneColor(Right, c = green, PL = 0, closed = True)
lj.DrawPL(0)
'''
# Red on laser 1 and green on laser 2
lj.PolyLineOneColor(Left, c = red, PL = 1, closed = True)
lj.PolyLineOneColor(Right, c = green, PL = 2, closed = True)
lj.DrawPL(1)
lj.DrawPL(2)
'''
time.sleep(0.1)
counter += 1
if counter >360:
counter =0
white = rgb2int(255,255,255)
red = rgb2int(255,0,0)
blue = rgb2int(0,0,255)

View File

@ -1,83 +0,0 @@
# coding=UTF-8
'''
Cycling text on one LJ laser.
LICENCE : CC
'''
import redis
import lj
import sys,time
import argparse
duration = 300
lasertext = ["TEAMLASER","FANFAN","LOLOSTER","SAM"]
'''
is_py2 = sys.version[0] == '2'
if is_py2:
from Queue import Queue
else:
from queue import Queue
'''
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Text Cycling for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int)
args = argsparser.parse_args()
if args.client:
ljclient = args.client
else:
ljclient = 0
if args.laser:
plnumber = args.laser
else:
plnumber = 0
# Redis Computer IP
if args.redisIP != None:
redisIP = args.redisIP
else:
redisIP = '127.0.0.1'
lj.Config(redisIP,ljclient)
#r = redis.StrictRedis(host=redisIP, port=6379, db=0)
# If you want to use rgb for color :
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
def Run():
counter =0
step = 0
timing = -1
color = rgb2int(255,255,255)
while 1:
if timing == duration or timing == -1:
message = lasertext[step]
lj.Text(message, color, PL = 0, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj.DrawPL(0)
timing = 0
else:
step += 1
if step >3:
step =0
timing += 1
time.sleep(0.01)
Run()

View File

@ -43,6 +43,9 @@ lsteps is a string like "[ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]"
/order value : instruct tracer what to do.
/planet will be forwarded to planetarium client.
/nozoid will be forwarded to nozoid client.
0 : display user pointlist with current client key. See below for client key.
1 : pull in redis a new correction matrix (EDH)
2 : display black
@ -83,6 +86,8 @@ import redis
r = redis.StrictRedis(host=gstt.LjayServerIP , port=6379, db=0)
GenericCommands = ["start","ljclient","clientnumber","noteon","pong","mouse","emergency","simu","status","run","nozoid","planet","live","words","ai","bank0"]
def UserOn(laser):
@ -161,16 +166,22 @@ def handler(oscpath, args):
print ""
print "OSC handler in commands.py got oscpath[1] :",oscpath[1], "with args :",args
# 2 incoming cases : generic or specific for a given lasernumber
# Need better programming
if oscpath[1] == "client" or oscpath[1] =="noteon" or oscpath[1]=="mouse" or oscpath[1]=="emergency" or oscpath[1]=="simu" or oscpath[1]=="status" or oscpath[1]=="run" or oscpath[1]=="nozoid" or oscpath[1]=="planet" or oscpath[1]=="live" or oscpath[1]=="planet" :
if oscpath[1] == "client":
# 2 incoming cases : generic or specific for a given lasernumber :
# Generic : Commands without a laser number
#if oscpath[1] == "client" or oscpath[1]=="clientnumber" or oscpath[1] =="noteon" or oscpath[1]=="pong" or oscpath[1]=="mouse" or oscpath[1]=="emergency" or oscpath[1]=="simu" or oscpath[1]=="status" or oscpath[1]=="run" or oscpath[1]=="nozoid" or oscpath[1]=="planet" or oscpath[1]=="live" or oscpath[1]=="planet" :
if oscpath[1] in GenericCommands:
if oscpath[1] == "ljclient":
LasClientChange(int(args[0]))
elif oscpath[1] == "noteon":
NoteOn(int(args[0]))
elif oscpath[1] == "pong":
print ""
print "Got pong from ",args
elif oscpath[1] == "mouse":
Mouse(int(args[0]),int(args[1]),int(args[2]),int(args[3]))
@ -187,7 +198,7 @@ def handler(oscpath, args):
print "Back to normal for laser ", laser
UserOn(laser)
# Commands with a laser number
else:
pathlength = len(oscpath)
@ -207,7 +218,7 @@ def handler(oscpath, args):
else:
print "No grid for laser ", laser
UserOn(laser)
# /ip/lasernumber value
if oscpath[1] == "ip":

View File

@ -102,8 +102,8 @@ JumpFlag =0
# OSC ports
#temporaray fix hack : iport=nozoport
iport = 8001 #LJay (bhorosc) input port
oport = 8002 #LJay (bhorosc) output port
iport = 8002 # LJ input port
oport = 8001 # LJ output port
noziport=8003 #nozosc.py receiving commands port
nozoport=8001 #nozosc.py sending port to LJay (main.py)
nozuport=0 #linux serial usb port connecting nozoid devices ACM0 by default

179
main.py
View File

@ -2,16 +2,26 @@
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
LJ Laser Server v0.8
LJ Laser Server v0.8.1
Laser server + webUI servers (ws + OSC)
- get point list to draw : /pl/lasernumber
- for report /lstt/lasernumber /lack/lasernumber /cap/lasernumber
- A nice ws debug tool : websocat
- a "plugin" is a code that send point to LJ. Plugins if they have an open OSC port can be checked and restart if in the same computer.
todo :
Todo :
- If no plugin ping is not received, restart the plugin.
- upgrade to python3
All used ports:
8002 OSC incoming
9001 WS communication with WebGUI
Plugins Ports (see LJ.conf)
'''
@ -22,8 +32,8 @@ import redis
print ""
print ""
print "LJ Laser Servers"
print "v0.8.0"
print "LJ Laser Server"
print "v0.8.1"
print ""
import settings
@ -39,11 +49,15 @@ import homographyp
import commands
import font1
import subprocess
import sys
import os
from OSC import OSCServer, OSCClient, OSCMessage
from websocket_server import WebsocketServer
#import socket
import types, thread, time
import plugins
r = redis.StrictRedis(host=gstt.LjayServerIP , port=6379, db=0)
args =[0,0]
@ -108,14 +122,18 @@ extoscPORTout = 8001
# With Nozoid
# OSC Client : to send OSC message to Nozoid inport 8003
NozoscIPout = nozoscIP
NozoscPORTout = 8003
NozoscPORTout = plugins.Port("nozoid")
# With Planetarium
# OSC Client : to send OSC message to planetarium inport 8005
planetIPout = nozoscIP
planetPORTout = 8005
planetPORTout = plugins.Port("planet")
# With Bank0
# OSC Client : to send OSC message to bank0 inport 8010
bank0IPout = nozoscIP
bank0PORTout = plugins.Port("bank0")
oscserver = OSCServer( (extoscIPin, extoscPORTin) )
oscserver.timeout = 0
@ -127,6 +145,7 @@ def handle_timeout(self):
oscserver.handle_timeout = types.MethodType(handle_timeout, oscserver)
'''
osclientext = OSCClient()
oscmsg = OSCMessage()
osclientext.connect((extoscIPout, extoscPORTout))
@ -198,6 +217,31 @@ def sendplanet(oscaddress,oscargs=''):
#time.sleep(0.001)
# send UI string as OSC message to Bank 0 8010
# sendbank0(oscaddress, [arg1, arg2,...])
osclientbank0 = OSCClient()
osclientbank0.connect((planetIPout, planetPORTout))
def sendbank0(oscaddress,oscargs=''):
oscmsg = OSCMessage()
oscmsg.setAddress(oscaddress)
oscmsg.append(oscargs)
print "Sending OSC to Bank0 server :", oscaddress,'with args :', oscargs
try:
osclientbank0.sendto(oscmsg, (bank0IPout, bank0PORTout))
oscmsg.clearData()
except:
print 'OSC send to bank0 IP', bank0IPout, 'port', bank0PORTout, "refused : died ?"
sendWSall("/bank0/start 0")
sendWSall("/status No Bank0")
#time.sleep(0.001)
'''
# OSC default path handler : send incoming OSC message to UI via websocket 9001
def handler(path, tags, args, source):
@ -210,7 +254,6 @@ def handler(path, tags, args, source):
# print "OSC said path", path," oscpath ", oscpath," args", args
sendWSall(path + " " + str(args[0]))
commands.handler(oscpath,args)
@ -280,14 +323,12 @@ def osc_thread():
traceback.print_tb(sys.exc_info()[2])
print "\n"
#
# Websocket part
#
# Called for every WS client connecting (after handshake)
def new_client(client, server):
def new_client(client, wserver):
print("New WS client connected and was given id %d" % client['id'])
sendWSall("/status Hello %d" % client['id'])
@ -307,12 +348,13 @@ def new_client(client, server):
sendWSall("/swap/Y/" + str(laserid)+ " 0")
# Called for every WS client disconnecting
def client_left(client, server):
def client_left(client, wserver):
print("WS Client(%d) disconnected" % client['id'])
# Called for each ws received message.
def message_received(client, server, message):
# Called for each WS received message.
def message_received(client, wserver, message):
if len(message) > 200:
message = message[:200]+'..'
@ -325,19 +367,65 @@ def message_received(client, server, message):
oscpath = message.split(" ")
print "WS Client", client['id'], "said :", message, "splitted in an oscpath :", oscpath
# If message included "planet" forward the message as OSC to planet IP port 8005
if oscpath[0].find("planet") != -1:
if len(oscpath) == 1:
sendplanet(oscpath[0], oscargs='noargs')
else:
sendplanet(oscpath[0], oscargs=oscpath[1])
for plugin in gstt.plugins.keys():
if plugins.Send(plugin,oscpath):
print "Plugin", plugin, "processed",oscpath
'''
if plugins.Send("planet",oscpath):
pass
# If message included "nozoid" forward the message as OSC to nozoid IP port 8003
elif oscpath[0].find("nozoid") != -1:
if len(oscpath) == 1:
sendnozosc(oscpath[0], oscargs='noargs')
elif plugins.Send("nozoid",oscpath):
pass
elif plugins.Send("ai",oscpath):
pass
elif plugins.Send("lissa",oscpath):
pass
elif plugins.Send("bank0",oscpath):
pass
elif plugins.Send("simu",oscpath):
pass
elif len(oscpath) > 1:
args[0] = str(oscpath[1])
commands.handler(oscpath[0].split("/"),args)
#print oscpath[0].split("/"),oscpath[1]
# current UI has no dedicated off button so /on 0 trigs /off to extosc
if oscpath[0] == "/on":
if oscpath[1] == "1":
sendextosc("/on")
else:
sendnozosc(oscpath[0], oscargs=oscpath[1])
sendextosc("/off")
'''
if len(oscpath) == 1:
args[0] = "noargs"
commands.handler(oscpath[0].split("/"),args)
'''
# I message included "nozoid" forward the message as OSC to nozoid IP port 8003
elif oscpath[0].find("nozoid") != -1:
if plugins.Ping("nozoid"):
sendWSall("/nozoid/start 1")
if oscpath[0].find("start") != -1:
print "Nozoid 0",oscpath[0],"1", oscpath[1]
if len(oscpath) == 1:
sendnozosc(oscpath[0], oscargs='noargs')
else:
sendnozosc(oscpath[0], oscargs=oscpath[1])
else:
sendWSall("/status Nozoid offline")
sendWSall("/planet/start 0")
# If message included "ai" do something
elif oscpath[0].find("ai") != -1:
@ -347,26 +435,19 @@ def message_received(client, server, message):
elif oscpath[0].find("lissa") != -1:
print "lissa order ", oscpath
# If message included "vj" do something
elif oscpath[0].find("vj") != -1:
print "VJ order ", oscpath
# If message included "bank0" do something
elif oscpath[0].find("bank0") != -1:
elif len(oscpath) > 1:
args[0] = str(oscpath[1])
#print oscpath[0].split("/"),oscpath[1]
# current UI has no dedicated off button so /on 0 trigs /off to extosc
elif oscpath[0] == "/on":
if oscpath[1] == "1":
sendextosc("/on")
if plugins.Ping("bank0"):
if len(oscpath) == 1:
sendbank0(oscpath[0], oscargs='noargs')
else:
sendbank0(oscpath[0], oscargs=oscpath[1])
else:
sendextosc("/off")
sendWSall("/status Bank0 offline")
'''
else:
args[0] = "noargs"
commands.handler(oscpath[0].split("/"),args)
# if needed a loop back : WS Client -> server -> WS Client
#sendWSall("ws"+message)
@ -378,7 +459,7 @@ def handle_timeout(self):
def sendWSall(message):
#if gstt.debug >0:
#print("WS sending %s" % (message))
server.send_message_to_all(message)
wserver.send_message_to_all(message)
@ -425,12 +506,14 @@ if lasernumber >2:
print "Launching Laser 3 Process..."
dac_worker3.start()
# Main loop do nothing. Maybe do the webui server ?
try:
#while True:
# Websocket startup
server = WebsocketServer(wsPORT,host=serverIP)
wserver = WebsocketServer(wsPORT,host=serverIP)
plugins.Init(wserver)
# Launch OSC thread listening to extosc
print ""
@ -444,13 +527,13 @@ try:
#print server
#print wserver
print ""
print "Launching webUI Websocket server..."
print "at", serverIP, "port",wsPORT
server.set_fn_new_client(new_client)
server.set_fn_client_left(client_left)
server.set_fn_message_received(message_received)
wserver.set_fn_new_client(new_client)
wserver.set_fn_client_left(client_left)
wserver.set_fn_message_received(message_received)
print ""
print "Resetting all Homographies.."
for laserid in range(0,gstt.LaserNumber):
@ -458,7 +541,7 @@ try:
print ""
print "ws server running forver..."
server.run_forever()
wserver.run_forever()
except KeyboardInterrupt:

181
plugins.py Normal file
View File

@ -0,0 +1,181 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
LJ Laser Server v0.8.1
Plugins Handler.
'''
from OSC import OSCServer, OSCClient, OSCMessage
from websocket_server import WebsocketServer
import gstt
import os
import subprocess
import sys
def Init(wserver):
global WSserver
WSserver = wserver
def sendWSall(message):
#if gstt.debug >0:
#print("WS sending %s" % (message))
WSserver.send_message_to_all(message)
# What is plugin's OSC port ?
def Port(name):
data = gstt.plugins.get(name)
return data.get("OSC")
# How to start the plugin ?
def Command(name):
data = gstt.plugins.get(name)
return data.get("command")
# Get all plugin current state
def Data(name):
return gstt.plugins.get(name)
def Start(name):
# get Plugin configuration.
command = Command(name)
# Maybe it's not fully started
data = Data(name)
if command != "" and "pid" not in data :
sendWSall("/status Starting...")
# Get LJ path
ljpath = r'%s' % os.getcwd().replace('\\','/')
print ""
print "Starting plugin :", name
print "LJ path :", ljpath
# Construct the command with absolute path.
PluginPath = command.split(" ")
# Launch as a subprocess
PluginProcess = subprocess.Popen([PluginPath[0], ljpath + "/" + PluginPath[1]])
print "New process pid for ", name, ":", PluginProcess.pid
data = Data(name)
data["pid"] = PluginProcess.pid
data["process"] = PluginProcess
# Process can be terminated with :
# PluginProcess.terminate()
def OSCsend(name, oscaddress, oscargs =''):
PluginPort = Port(name)
sendWSall("/status Checking "+ name + "...")
if gstt.debug >0:
print ""
print "Checking plugin ",name, "..."
print "Plugin ", name, "is at", gstt.LjayServerIP, "and has OSC port : " + str(PluginPort)
print "Sending", oscaddress, oscargs,"to plugin ", name
osclientplugin = OSCClient()
osclientplugin.connect((gstt.LjayServerIP, PluginPort))
oscmsg = OSCMessage()
oscmsg.setAddress(oscaddress)
oscmsg.append(oscargs)
try:
osclientplugin.sendto(oscmsg, (gstt.LjayServerIP, PluginPort))
oscmsg.clearData()
if gstt.debug >0:
print oscaddress, oscargs, "was sent to",name
return True
except:
print ""
print 'Connection to plugin IP', gstt.LjayServerIP ,'port', PluginPort,' refused : died ?'
#sendWSall("/status No plugin.")
sendWSall("/status No plugin.")
#PluginStart(name)
return False
def Ping(name):
return OSCsend(name,"/ping")
def Kill(name):
data = Data(name)
print ""
if data["process"] != None:
print name, "plugin is owned by LJ."
print "Killing plugin", name
OSCsend(name,"/quit")
#data["process"].terminate()
sendWSall("/status Killing "+ name +".")
else:
print "Killing asked but plugin is not owned by LJ"
sendWSall("/status Not own plugin")
# Send a command to given plugin. Will also start it if command contain /start 1
def Send(name,oscpath):
if oscpath[0].find(name) != -1:
# Plugin is online ?
if Ping(name):
# Light up the plugin button
sendWSall("/" + name + "/start 1")
sendWSall("/status " + name + " online")
if gstt.debug >0:
print "Plugin " + name + " online."
print "Command", oscpath
# If start 0, try to kill plugin
if oscpath[0].find("start") != -1 and oscpath[1] == "0":
if gstt.debug >0:
print "start 0, so killing", name, "..."
Kill(name)
# Send osc command
elif len(oscpath) == 1:
OSCsend(name,oscpath[0], oscargs='noargs')
else:
OSCsend(name,oscpath[0], oscargs=oscpath[1])
return True
# Plugin not online..
else:
if gstt.debug >0:
print "Plugin " + name + " offline."
print "Command", oscpath
sendWSall("/status Plugin " + name + " offline")
sendWSall("/"+ name + "/start 0")
# Try to Start it if /start 1
if oscpath[0].find("start") != -1 and oscpath[1] == "1":
if gstt.debug >0:
print "Trying to start", name, "..."
Start(name)
return False

706
plugins/VJing/bank0.py Normal file
View File

@ -0,0 +1,706 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
VJing Bank 0
was Franken for compo laser at coockie 2018 demoparty
0 : many Starfields
1 : generic pose animations
2 : Faces
3 : Dancers
LICENCE : CC
Sam Neurohack, Loloster,
'''
import math
#import gstt
#from globalVars import *
import numpy as np
import pdb
from datetime import datetime
from random import randrange
import redis
import lj3
import sys,time
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
#from osc4py3 import oscmethod as osm
from osc4py3.oscmethod import *
import argparse
#f_sine = 0
screen_size = [400,400]
xy_center = [screen_size[0]/2,screen_size[1]/2]
message = "Hello"
OSCinPort = 8010
redisIP = '127.0.0.1'
ljclient = 0
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="VJ Bank 0 for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-v","--verbose",help="Verbosity level (0 by default)",type=int)
args = argsparser.parse_args()
if args.verbose:
debug = args.verbose
else:
debug = 0
if args.client:
ljclient = args.client
else:
ljclient = 0
# Redis Computer IP
if args.redisIP != None:
redisIP = args.redisIP
else:
redisIP = '127.0.0.1'
lj3.Config(redisIP,ljclient)
def OSCljclient(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /bank0/ljclient with value", value)
ljclient = value
lj3.LjClient(ljclient)
def hex2rgb(hexcode):
return tuple(map(ord,hexcode[1:].decode('hex')))
def rgb2hex(rgb):
return int('0x%02x%02x%02x' % tuple(rgb),0)
# Curve 0 many starfields
def prepareSTARFIELD():
global star, stars0, stars1, stars2, starfieldcount, starspeed, displayedstars, displayedstars, num_stars, max_depth
stars0=[]
stars1=[]
stars2=[]
#stars3=[]
num_stars = 50
max_depth = 20
stars = []
starfieldcount = 0
displayedstars = 5
starspeed = 0.05
for i in range(num_stars):
# A star is represented as a list with this format: [X,Y,Z]
star = [randrange(-25,25), randrange(-25,25), randrange(1, max_depth)]
stars0.append(star)
star = [randrange(-25,25), randrange(-25,25), randrange(1, max_depth)]
stars1.append(star)
star = [randrange(-25,25), randrange(-25,25), randrange(1, max_depth)]
stars2.append(star)
def Starfield(hori=0,verti=0):
global star, stars0, stars1, stars2, starfieldcount, starspeed, displayedstars, displayedstars, num_stars, max_depth
starfieldcount += 1
#print starfieldcount
starpoints = []
# Move starfield according to joypads. Not used in the demo
'''
# Tflight joystick :
# y axis 1 top -1 bottom 1
# x axis 0 left -1 right 1
# Main fire button 5
# hat (x,y) x -1 left x 1 right y -1 bottom y 1 top
# speed axis 3 backward 1 forward -1
if Nbpads > 0:
# Move center on X axis according to pad
if pad1.get_axis(0)<-0.1 or pad1.get_axis(0)>0.1:
hori = pad1.get_axis(0)
#print hori
# Move center on Y axis according to pad
if pad1.get_axis(1)<-0.1 or pad1.get_axis(1)>0.1:
verti= pad1.get_axis(1)
#print verti
'''
#print displayedstars, 'stars displayed'
# Increase number of
if displayedstars < num_stars and starfieldcount % 15 == 0:
displayedstars += 1
if displayedstars == num_stars and starfieldcount % 10 == 0:
starspeed += 0.005
#if Nbpads > 0:
# starspeed = (1-pad1.get_axis(3))
#print starspeed
for starnumber in range(0,displayedstars):
# The Z component is decreased on each frame.
stars0[starnumber][2] -= starspeed * 3
stars1[starnumber][2] -= starspeed * 3
stars2[starnumber][2] -= starspeed * 3
# If the star has past the screen (I mean Z<=0) then we
# reposition it far away from the screen (Z=max_depth)
# with random X and Y coordinates.
if stars0[starnumber][2] <= 0:
stars0[starnumber][0] = randrange(-25,25)
stars0[starnumber][1] = randrange(-25,25)
stars0[starnumber][2] = max_depth
if stars1[starnumber][2] <= 0:
stars1[starnumber][0] = randrange(-25,25)
stars1[starnumber][1] = randrange(-25,25)
stars1[starnumber][2] = max_depth
if stars2[starnumber][2] <= 0:
stars2[starnumber][0] = randrange(-25,25)
stars2[starnumber][1] = randrange(-25,25)
stars2[starnumber][2] = max_depth
# Convert the 3D coordinates to 2D using perspective projection.
k0 = 128.0 / stars0[starnumber][2]
k1 = 128.0 / stars1[starnumber][2]
k2 = 128.0 / stars2[starnumber][2]
# Move Starfield origin.
# if stars xpos/ypos is same sign (i.e left stars xpos is <0) than (joystick or code) acceleration (hori and verti moves the star field origin)
if np.sign(stars0[starnumber][0]) == np.sign(hori):
x0 = int(stars0[starnumber][0] * k0 + xy_center[0] + (hori*600))
else:
x0 = int(stars0[starnumber][0] * k0 + xy_center[0] + (hori*300))
if np.sign(stars0[starnumber][1]) == np.sign(verti):
y0 = int(stars0[starnumber][1] * k0 + xy_center[1] + (verti*600))
else:
y0 = int(stars0[starnumber][1] * k0 + xy_center[1] + (verti*300))
if np.sign(stars1[starnumber][0]) == np.sign(hori):
x1 = int(stars1[starnumber][0] * k1 + xy_center[0] + (hori*600))
else:
x1 = int(stars1[starnumber][0] * k1 + xy_center[0] + (hori*300))
if np.sign(stars1[starnumber][1]) == np.sign(verti):
y1 = int(stars1[starnumber][1] * k1 + xy_center[1] + (verti*600))
else:
y1 = int(stars1[starnumber][1] * k1 + xy_center[1] + (verti*300))
if np.sign(stars2[starnumber][0]) == np.sign(hori):
x2 = int(stars2[starnumber][0] * k2 + xy_center[0] + (hori*600))
else:
x2 = int(stars2[starnumber][0] * k2 + xy_center[0] + (hori*300))
if np.sign(stars2[starnumber][1]) == np.sign(verti):
y2 = int(stars2[starnumber][1] * k2 + xy_center[1] + (verti*600))
else:
y2 = int(stars2[starnumber][1] * k2 + xy_center[1] + (verti*300))
# Add star to pointlist PL 0
if 0 <= x0 < screen_size[0] - 2 and 0 <= y0 < screen_size[1] - 2:
#f.LineTo((x,y), 0x80000000)
lj3.PolyLineOneColor([(x0,y0),((x0+1),(y0+1))], c = rgb2hex([255,255,255]), PL = 0, closed = False)
#fwork.PolyLineOneColor([(x0,y0),((x0+1),(y0+1))], c=rgb2hex([255,255,255]), PL = 0, closed = False)
# Add star to pointlist PL 1
if 0 <= x1 < screen_size[0] - 2 and 0 <= y1 < screen_size[1] - 2:
lj3.PolyLineOneColor([(x1,y1),((x1+1),(y1+1))], c = rgb2hex([255,255,255]), PL = 0, closed = False)
#fwork.PolyLineOneColor([(x1,y1),((x1+1),(y1+1))], c=rgb2hex([255,255,255]), PL = 1, closed = False)
# Add star to pointlist PL 2
#if 0 <= x2 < screen_size[0] - 2 and 0 <= y2 < screen_size[1] - 2:
# fwork.PolyLineOneColor([(x2,y2),((x2+1),(y2+1))], c=colorify.rgb2hex([255,255,255]), PL = 2, closed = False)
# #f.PolyLineOneColor([(x,y),((x+2),(y+2))], COLOR_WHITE)
'''
if starfieldcount < 200:
if 0 <= x3 < screen_size[0] - 2 and 0 <= y3 < screen_size[1] - 2:
fwork.PolyLineOneColor([(x3,y3),((x3+2),(y3+2))], c=colorify.rgb2hex([255,255,255]), PL = 3, closed = False)
'''
lj3.Text(message, color, PL = 2, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj3.DrawPL(0)
lj3.DrawPL(1)
lj3.DrawPL(2)
#lj3.DrawPL(3)
# Curve 1 : generic pose animations
import json
CurrentPose = 1
# get absolute body position points
def getCOCO(pose_json,pose_points, people):
dots = []
for dot in pose_points:
if len(pose_json['part_candidates'][people][str(dot)]) != 0:
dots.append((pose_json['part_candidates'][people][str(dot)][0], pose_json['part_candidates'][people][str(dot)][1]))
return dots
# get relative (-1 0 1) body position points. a position -1, -1 means doesn't exist
def getBODY(pose_json,pose_points, people):
dots = []
for dot in pose_points:
#print pose_points
if len(pose_json['people'][people]['pose_keypoints_2d']) != 0:
#print "people 0"
if pose_json['people'][people]['pose_keypoints_2d'][dot * 3] != -1 and pose_json['people'][people]['pose_keypoints_2d'][(dot * 3)+1] != -1:
dots.append((pose_json['people'][people]['pose_keypoints_2d'][dot * 3], pose_json['people'][people]['pose_keypoints_2d'][(dot * 3)+1]))
return dots
# get absolute face position points
def getFACE(pose_json,pose_points, people):
dots = []
for dot in pose_points:
if len(pose_json['people'][people]['face_keypoints_2d']) != 0:
#print "people 0"
if pose_json['people'][people]['face_keypoints_2d'][dot * 3] != -1 and pose_json['people'][people]['face_keypoints_2d'][(dot * 3)+1] != -1:
dots.append((pose_json['people'][people]['face_keypoints_2d'][dot * 3], pose_json['people'][people]['face_keypoints_2d'][(dot * 3)+1]))
return dots
# Body parts
def bodyCOCO(pose_json, people):
pose_points = [10,9,8,1,11,12,13]
return getBODY(pose_json,pose_points, people)
def armCOCO(pose_json, people):
pose_points = [7,6,5,1,2,3,4]
return getBODY(pose_json,pose_points, people)
def headCOCO(pose_json, people):
pose_points = [1,0]
return getBODY(pose_json,pose_points, people)
# Face keypoints
def face(pose_json, people):
pose_points = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
return getFACE(pose_json,pose_points, people)
def browL(pose_json, people):
pose_points = [26,25,24,23,22]
return getFACE(pose_json,pose_points, people)
def browR(pose_json, people):
pose_points = [21,20,19,18,17]
return getFACE(pose_json,pose_points, people)
def eyeR(pose_json, people):
pose_points = [36,37,38,39,40,41,36]
return getFACE(pose_json,pose_points, people)
def eyeL(pose_json, people):
pose_points = [42,43,44,45,46,47,42]
return getFACE(pose_json,pose_points, people)
def nose(pose_json, people):
pose_points = [27,28,29,30]
return getFACE(pose_json,pose_points, people)
def mouth(pose_json, people):
pose_points = [48,59,58,57,56,55,54,53,52,51,50,49,48,60,67,66,65,64,63,62,61,60]
return getFACE(pose_json,pose_points, people)
import os
# Get frame number for pose path describe in PoseDir
def lengthPOSE(pose_dir):
if debug > 0:
print("Check directory",'poses/' + pose_dir)
if os.path.exists('poses/' + pose_dir):
numfiles = sum(1 for f in os.listdir('poses/' + pose_dir) if os.path.isfile(os.path.join('poses/' + pose_dir + '/', f)) and f[0] != '.')
if debug > 0:
print(numfiles,"images")
return numfiles
else:
if debug > 0:
print("but it doesn't even exist!")
return 0
def preparePOSE():
global anims0, anims1, anims2
# anim format (name, xpos,ypos, resize, currentframe, totalframe, count, speed)
# total frames is fetched from directory file count
anims1 = [['sky',50,100,300,0,0,0,1],['2dancer1', 400,100, 300,0,0,0,1],['1dancer', 400,100, 300,0,0,0,1],['window1',100,100,300,0,0,0,1]]
anims2 = [['window1', 400,200, 300,0,0,0,1],['2dancer1',100,200,300,0,0,0,1]]
for anim in anims1:
anim[5]= lengthPOSE(anim[0])
anims0 = anims1
# display n pose animations on Laser 0
def Pose():
global anims0, anims1, anims2
for anim in anims0:
PL = 0
dots = []
print(anim, anim[5])
# repeat anim[7] time the same frame
anim[6] +=1
if anim[6] == anim[7]:
anim[6] = 0
# increase current frame and compare to total frame
anim[4] += 1
if anim[4] == anim[5]:
anim[4] = 0
posename = 'poses/' + anim[0] + '/' + anim[0] +'-'+str("%05d"%anim[4])+'.json'
posefile = open(posename , 'r')
posedatas = posefile.read()
pose_json = json.loads(posedatas)
for people in range(len(pose_json['people'])):
lj3.rPolyLineOneColor(bodyCOCO(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(armCOCO(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(headCOCO(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
# Face
'''
#lj3.rPolyLineOneColor(face(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(browL(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(browR(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(eyeR(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(eyeL(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(nose(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(mouth(pose_json, people), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
'''
lj3.DrawPL(PL)
time.sleep(0.02)
# decrease current frame
if keystates[pygame.K_w]: # and not keystates_prev[pygame.K_w]:
CurrentPose -= 1
if CurrentPose < 2:
CurrentPose = numfiles -1
#time.sleep(0.033)
print("Frame : ",CurrentPose)
# increaser current frame
if keystates[pygame.K_x]: # and not keystates_prev[pygame.K_x]:
CurrentPose += 1
if CurrentPose > numfiles -1:
CurrentPose = 1
#time.sleep(0.033)
print("Frame : ",CurrentPose)
# Curve 2 Faces
import json
CurrentPose = 1
def prepareFACES():
# anim format (name, xpos,ypos, resize, currentframe, totalframe, count, speed)
# total frame is fetched from directory file count
anims[0] = [['detroit1', 300,300, 100,0,0,0,1]]
anims[1] = [['detroit1', 400,200, 200,0,0,0,1]]
anims[2] = [['detroit1', 500,200, 300,0,0,0,1]]
'''
# read anims number of frames from disk.
for anim in range(len(anims0)):
anims0[anim][5]= lengthPOSE(anims0[anim][0])
for anim in range(len(anims1)):
anims1[anim][5]= lengthPOSE(anims1[anim][0])
for anim in range(len(anims2)):
anims2[anim][5]= lengthPOSE(anims2[anim][0])
'''
#replace code below
'''
for laseranims in range(3):
if debug > 0:
print "anims:",anims[laseranims],
for anim in range(len(anims[laseranims])):
anims[laseranims][anim][5]= lengthPOSE(anims[laseranims][anim][0])
if debug > 1:
print anims[laseranims][anim][5]
'''
#by this one
#thanks to https://stackoverflow.com/questions/19184335/is-there-a-need-for-rangelena
for laseranims in anims:
if debug > 1:
print("anims:",laseranims)
for anim in laseranims:
anim[5]=lengthPOSE(anim[0])
if debug > 1:
print(anim[5])
# display the face animation describe in PoseDir
def Faces():
for laseranims in range(3):
for anim in anims[laseranims]:
PL = laseranims
#print PL, anim
dots = []
#print anim, anim[5]
# repeat anim[7] time the same frame
anim[6] +=1
if anim[6] == anim[7]:
anim[6] = 0
# increase current frame and compare to total frame
anim[4] += 1
if anim[4] == anim[5]:
anim[4] = 0
posename = 'poses/' + anim[0] + '/' + anim[0] +'-'+str("%05d"%anim[4])+'.json'
posefile = open(posename , 'r')
posedatas = posefile.read()
pose_json = json.loads(posedatas)
# Face
for people in range(len(pose_json['people'])):
#lj3.PolyLineOneColor(face(pose), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(browL(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(browR(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(eyeR(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(eyeL(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(nose(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(mouth(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.DrawPL(PL)
time.sleep(0.02)
# Curve 3
# Dancers
import json
CurrentPose = 1
def prepareDANCERS():
# anim format (name, xpos,ypos, resize, currentframe, totalframe, count, speed)
# total frame is fetched from directory file count
anims[0] = [['1dancer',500,200,300,0,0,0,10]]
anims[1] = [['2dancer1',500,200,300,0,0,0,10]]
anims[2] = [['window1',500,200,300,0,0,0,10]]
#anims[1] = [['2dancer1',100,200,300,0,0,0,10]]
#anims[2] = [['window1',400,200, 300,0,0,0,10]]
# read anims number of frames from disk.
for laseranims in range(3):
for anim in range(len(anims[laseranims])):
anims[laseranims][anim][5]= lengthPOSE(anims[laseranims][anim][0])
# display the pose animation describe in PoseDir
def Dancers():
for laseranims in range(3):
for anim in anims[laseranims]:
PL = laseranims
#print PL, anim
dots = []
#print anim, anim[5]
# repeat anim[7] time the same frame
anim[6] +=1
if anim[6] == anim[7]:
anim[6] = 0
# increase current frame and compare to total frame
anim[4] += 1
if anim[4] == anim[5]:
anim[4] = 0
#bhorosc.sendresol("/layer1/clip1/connect",1)
#bhorosc.sendresol("/layer1/clip1/connect",0)
posename = 'poses/' + anim[0] + '/' + anim[0] +'-'+str("%05d"%anim[4])+'.json'
posefile = open(posename , 'r')
posedatas = posefile.read()
pose_json = json.loads(posedatas)
for people in range(len(pose_json['people'])):
lj3.rPolyLineOneColor(bodyCOCO(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(armCOCO(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(browL(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(browR(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(eyeR(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(eyeL(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(nose(pose_json, people), c=color, PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.rPolyLineOneColor(mouth(pose_json, people), c=color, PL = laseranims, closed = False,xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.DrawPL(PL)
'''
lj3.PolyLineOneColor(bodyCOCO(pose_json), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.PolyLineOneColor(armCOCO(pose_json), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
lj3.PolyLineOneColor(headCOCO(pose_json), c=color, PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
PL[PL] = fwork.LinesPL(PL)
'''
def OSCljclient(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /bank0/ljclient with value", value)
ljclient = value
lj3.LjClient(ljclient)
# Dancers, Starfield, Pose, Face
def OSCrun(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /run with value", value)
doit = value
def WebStatus(message):
lj3.Send("/status",message)
#doit = Starfield
doit = Pose
#doit = Faces
#doit = Dancers
print('Loading Bank0...')
WebStatus("Load Bank0")
# OSC Server callbacks
print("Starting OSC at 127.0.0.1 port",OSCinPort,"...")
osc_startup()
osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/bank0/run*", OSCrun)
osc_method("/bank0/ping*", lj3.OSCping)
osc_method("/bank0/ljclient", OSCljclient)
import pygame
pygame.init()
Nbpads = pygame.joystick.get_count()
print ("Joypads : ", str(Nbpads))
'''
if Nbpads != 2:
print ('')
print ('')
print ("THIS VERSION NEEDS 2 PADS. PLEASE CONNECT THEM.")
print ('')
sys.exit()
'''
if Nbpads > 1:
pad2 = pygame.joystick.Joystick(1)
pad2.init()
print ("Pad2 :", pad2.get_name())
numButtons = pad2.get_numbuttons()
#print ("Axis Pad 2 :", str(pad2.get_numaxes()))
#print ("Buttons Pad 2 :" , str(numButtons))
# joy is pad abstraction to handle many different devices.
joy2 = lj3.setup_controls(pad2)
if Nbpads > 0:
pad1 = pygame.joystick.Joystick(0)
pad1.init()
print ("Pad1 :",pad1.get_name())
numButtons = pad1.get_numbuttons()
joy1 = lj3.setup_controls(pad1)
#print ("Axis Pad 1 :", str(pad1.get_numaxes()))
#print ("Buttons Pad 1 :" , str(numButtons))
anims =[[],[],[],[]]
color = lj3.rgb2int(255,255,255)
prepareSTARFIELD()
preparePOSE()
prepareDANCERS()
prepareFACES()
WebStatus("Bank0 ready.")
print("Bank0 ready")
def Run():
try:
while 1:
#Starfield(hori=0,verti=0)
doit()
except KeyboardInterrupt:
pass
# Gently stop on CTRL C
finally:
WebStatus("Bank0 Exit")
print("Stopping OSC...")
lj3.OSCstop()
print ("Bank0 Stopped.")
Run()

618
plugins/VJing/lj3.py Normal file
View File

@ -0,0 +1,618 @@
# coding=UTF-8
'''
LJ v0.8.1 in python3
Some LJ functions useful for python clients (was framy.py)
OSC functions commented, waiting working on OSC in python3
Config(redisIP, client number)
PolyLineOneColor
rPolyLineOneColor
Text(word, color, PL, xpos, ypos, resize, rotx, roty, rotz) : Display a word
Send(adress,message) : remote control. See commands.py
WebStatus(message) : display message on webui
DrawPL(point list number) : once you stacked all wanted elements, like 2 polylines, send them to lasers.
rgb2int(r,g,b)
OSCstart(): Start the OSC system.
OSCframe():
OSCstop(): Properly close the OSC system
OSCping(value): Answer to LJ pings
setup_controls(joystick)
XboxController : getLeftHori, getLeftVert, getRightHori, getRightVert, getLeftTrigger, getRightTrigger
Ps3Controller : getLeftHori, getLeftVert, getRightHori, getRightVert, getLeftTrigger, getRightTrigger, getUp, getDown, getLeft, getRight, getFire1, getFire2(self):
MySaitekController : getLeftHori,getLeftVert, getRightHori,getRightVert, getLeftTrigger,getRightTrigger
MyThrustController : getLeftHori, getLeftVert, getRightHori, getRightVert, getLeftTrigger, getRightTrigger
CSLController : getLeftHori,getLeftVert,getRightHori, getRightVert,getLeftTrigger,getRightTrigger,getFire1,getFire2
my USB Joystick : getUp,getDown,getLeft,getRight,etLeftTrigger, getRightTrigger,getFire1, getFire2
LICENCE : CC
Sam Neurohack
'''
import math
import redis
# Import needed modules from osc4py3
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
redisIP = '127.0.0.1'
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = 0
point_list = []
pl = [[],[],[],[]]
#
# OSC interaction with LJ
#
def OSCstart():
# Start the system.
osc_startup()
#osc_udp_client(redisIP, 8002, "LJ 8002")
def OSCframe():
#print("OSCprocess")
osc_process()
# Properly close the system. Todo
def OSCstop():
osc_terminate()
# Answer to LJ pings
def OSCping(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /ping with value", value)
Send("/pong",value)
def Send(oscaddress,oscargs=''):
try:
msg = oscbuildparse.OSCMessage(oscaddress, None, [oscargs])
osc_send(msg, "LJ 8002")
OSCframe()
except:
print ('Connection to LJ refused : died ?')
pass
'''
def handlerfunction(s, x, y):
# Will receive message data unpacked in s, x, y
pass
def handlerfunction2(address, s, x, y):
# Will receive message address, and message data flattened in s, x, y
pass
# Make server channels to receive packets.
osc_udp_server("127.0.0.1", 3721, "localhost")
osc_udp_server("0.0.0.0", 3724, "anotherserver")
'''
ASCII_GRAPHICS = [
# caracteres corrects
[(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)], #0
[(-20,30), (0,-30), (-20,30)], #1
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #2
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #3
[(30,10), (-30,10), (0,-30), (0,30)], #4
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #5
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #6
[(-30,-30), (30,-30), (-30,30)], #7
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #8
[(30,0), (-30,0), (-30,-10), (0,-30), (30,-30), (30,10), (0,30), (-30,30)], #9
# caracteres a implementer
[(-30,10), (30,-10), (30,10), (0,30), (-30,10), (-30,-10), (0,-30), (30,-10)], #:
[(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #;
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #<
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #=
[(30,10), (-30,10), (0,-30), (0,30)], #>
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #?
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #@
# Caracteres corrects
[(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A
[(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #B
[(30,30), (-30,30), (-30,-30), (30,-30)], #C
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30)], #D
[(30,30), (-30,30), (-30,-0), (30,0), (-30,0), (-30,-30), (30,-30)], #E
[(-30,30), (-30,-0), (30,0), (-30,0), (-30,-30), (30,-30)], #F
[(0,0), (30,0), (30,30), (-30,30), (-30,-30),(30,-30)], #G
[(-30,-30), (-30,30), (-30,0), (30,0), (30,30), (30,-30)], #H
[(0,30), (0,-30)], #I
[(-30,30), (0,-30), (0,-30), (-30,-30), (30,-30)], #J
[(-30,-30), (-30,30), (-30,0), (30,-30), (-30,0), (30,30)], #K
[(30,30), (-30,30), (-30,-30)], #L
[(-30,30), (-30,-30), (0,0), (30,-30), (30,30)], #M
[(-30,30), (-30,-30), (30,30), (30,-30)], #N
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30)], #O
[(-30,0), (30,0), (30,-30), (-30,-30), (-30,30)], #P
[(30,30), (30,-30), (-30,-30), (-30,30), (30,30),(35,35)], #Q
[(-30,30), (-30,-30), (30,-30), (30,0), (-30,0), (30,30)], #R
[(30,-30), (-30,-30), (-30,0), (30,0), (30,30), (-30,30)], #S
[(0,30), (0,-30), (-30,-30), (30,-30)], #T
[(-30,-30), (-30,30), (30,30), (30,-30)], #U
[(-30,-30), (0,30), (30,-30)], #V
[(-30,-30), (-30,30), (0,0), (30,30), (30,-30)], #W
[(-30,30), (30,-30)], [(-30,-30), (30,30)], #X
[(0,30), (0,0), (30,-30), (0,0), (-30,-30)], #Y
[(30,30), (-30,30), (30,-30), (-30,-30)], #Z
# A implementer
[(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #[
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #\
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #]
[(30,10), (-30,10), (0,-30), (0,30)], #^
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #_
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #`
# Implementé
[(-20,20), (-20,-20), (20,-20), (20,20), (20,0), (-20,0)], #a
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20), (-20,0), (20,0)], #b
[(20,20), (-20,20), (-20,-20), (20,-20)], #c
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20)], #d
[(20,20), (-20,20), (-20,-0), (20,0), (-20,0), (-20,-20), (20,-20)], #e
[(-20,20), (-20,-0), (20,0), (-20,0), (-20,-20), (20,-20)], #f
[(0,0), (20,0), (20,20), (-20,20), (-20,-20),(20,-20)], #g
[(-20,-20), (-20,20), (-20,0), (20,0), (20,20), (20,-20)], #H
[(0,20), (0,-20)], #I
[(-20,20), (0,-20), (0,-20), (-20,-20), (20,-20)], #J
[(-20,-20), (-20,20), (-20,0), (20,-20), (-20,0), (20,20)], #K
[(20,20), (-20,20), (-20,-20)], #L
[(-20,20), (-20,-20), (0,0), (20,-20), (20,20)], #M
[(-20,20), (-20,-20), (20,20), (20,-20)], #N
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20)], #O
[(-20,0), (20,0), (20,-20), (-20,-20), (-20,20)], #P
[(20,20), (20,-20), (-20,-20), (-20,20), (20,20),(25,25)], #Q
[(-20,20), (-20,-20), (20,-20), (20,0), (-20,0), (20,20)], #R
[(20,-20), (-20,-20), (-20,0), (20,0), (20,20), (-20,20)], #S
[(0,20), (0,-20), (-20,-20), (20,-20)], #T
[(-20,-20), (-20,20), (20,20), (20,-20)], #U
[(-20,-20), (0,20), (20,-20)], #V
[(-20,-20), (-20,20), (0,0), (20,20), (20,-20)], #W
[(-20,20), (20,-20)], [(-20,-20), (20,20)], #X
[(0,20), (0,0), (20,-20), (0,0), (-20,-20)], #Y
[(20,20), (-20,20), (20,-20), (-20,-20)], #Z
[(-2,15), (2,15)] # Point a la place de {
]
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
def Config(redisIP,client):
global ClientNumber
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = client
osc_udp_client(redisIP, 8002, "LJ 8002")
def LjClient(client):
global ClientNumber
ClientNumber = client
def LineTo(xy, c, PL):
pl[PL].append((xy + (c,)))
def Line(xy1, xy2, c, PL):
LineTo(xy1, 0, PL)
LineTo(xy2, c , PL)
def PolyLineOneColor(xy_list, c, PL , closed ):
#print "--"
#print "c",c
#print "xy_list",xy_list
#print "--"
xy0 = None
for xy in xy_list:
if xy0 is None:
xy0 = xy
#print "xy0:",xy0
LineTo(xy0,0, PL)
LineTo(xy0,c, PL)
else:
#print "xy:",xy
LineTo(xy,c, PL)
if closed:
LineTo(xy0,c, PL)
# Computing points coordinates for rPolyline function from 3D and around 0,0 to pygame coordinates
def Pointransf(xy, xpos = 0, ypos =0, resize =1, rotx =0, roty =0 , rotz=0):
x = xy[0] * resize
y = xy[1] * resize
z = 0
rad = rotx * math.pi / 180
cosaX = math.cos(rad)
sinaX = math.sin(rad)
y2 = y
y = y2 * cosaX - z * sinaX
z = y2 * sinaX + z * cosaX
rad = roty * math.pi / 180
cosaY = math.cos(rad)
sinaY = math.sin(rad)
z2 = z
z = z2 * cosaY - x * sinaY
x = z2 * sinaY + x * cosaY
rad = rotz * math.pi / 180
cosZ = math.cos(rad)
sinZ = math.sin(rad)
x2 = x
x = x2 * cosZ - y * sinZ
y = x2 * sinZ + y * cosZ
#print xy, (x + xpos,y+ ypos)
return (x + xpos,y+ ypos)
'''
to understand why it get negative Y
# 3D to 2D projection
factor = 4 * gstt.cc[22] / ((gstt.cc[21] * 8) + z)
print xy, (x * factor + xpos, - y * factor + ypos )
return (x * factor + xpos, - y * factor + ypos )
'''
# Send 2D point list around 0,0 with 3D rotation resizing and reposition around xpos ypos
#def rPolyLineOneColor(self, xy_list, c, PL , closed, xpos = 0, ypos =0, resize =1, rotx =0, roty =0 , rotz=0):
def rPolyLineOneColor(xy_list, c, PL , closed, xpos = 0, ypos =0, resize =0.7, rotx =0, roty =0 , rotz=0):
xy0 = None
for xy in xy_list:
if xy0 is None:
xy0 = xy
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),0, PL)
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),c, PL)
else:
LineTo(Pointransf(xy, xpos, ypos, resize, rotx, roty, rotz),c, PL)
if closed:
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),c, PL)
def LinesPL(PL):
print ("Stupido !! your code is to old : use DrawPL() instead of LinesPL()")
DrawPL(PL)
def DrawPL(PL):
#print '/pl/0/'+str(PL), str(pl[PL])
if r.set('/pl/'+str(ClientNumber)+'/'+str(PL), str(pl[PL])) == True:
pl[PL] = []
return True
else:
return False
def ResetPL(self, PL):
pl[PL] = []
def DigitsDots(number,color):
dots =[]
for dot in ASCII_GRAPHICS[number]:
#print dot
dots.append((gstt.xy_center[0]+dot[0],gstt.xy_center[1]+dot[1],color))
#self.point_list.append((xy + (c,)))
return dots
def CharDots(char,color):
dots =[]
for dot in ASCII_GRAPHICS[ord(char)-46]:
dots.append((dot[0],dot[1],color))
return dots
def Text(message,c, PL, xpos, ypos, resize, rotx, roty, rotz):
dots =[]
l = len(message)
i= 0
#print message
for ch in message:
#print ""
# texte centre en x automatiquement selon le nombre de lettres l
x_offset = 26 * (- (0.9*l) + 3*i)
#print i,x_offset
# if digit
if ord(ch)<58:
char_pl_list = ASCII_GRAPHICS[ord(ch) - 48]
else:
char_pl_list = ASCII_GRAPHICS[ord(ch) - 46 ]
char_draw = []
#dots.append((char_pl_list[0][0] + x_offset,char_pl_list[0][1],0))
for xy in char_pl_list:
char_draw.append((xy[0] + x_offset,xy[1],c))
i +=1
#print ch,char_pl_list,char_draw
rPolyLineOneColor(char_draw, c, PL , False, xpos, ypos, resize, rotx, roty, rotz)
#print ("laser",PL,"message",message)
#dots.append(char_draw)
import re
def setup_controls(joystick):
"""
Joystick wrapper.
"""
if re.search('playstation', joystick.get_name(), re.I):
return Ps3Controller(joystick)
elif re.search('X-box', joystick.get_name(), re.I):
return XboxController(joystick)
elif re.search('Saitek', joystick.get_name(), re.I):
return MySaitekController(joystick)
elif re.search('Thrustmaster dual analog 3.2', joystick.get_name(), re.I):
return MyThrustController(joystick)
elif re.search('2n1 USB', joystick.get_name(), re.I):
return CSLController(joystick)
elif re.search('Joystick', joystick.get_name(), re.I):
return USBController(joystick)
return Controller(joystick)
class Controller(object):
def __init__(self, joystick):
"""Pass a PyGame joystick instance."""
self.js = joystick
def getLeftHori(self):
return self.js.get_axis(2)
def getLeftVert(self):
return self.js.get_axis(3)
def getRightHori(self):
return self.js.get_axis(0)
def getRightVert(self):
return self.js.get_axis(1)
def getLeftTrigger(self):
return self.js.get_button(9)
def getRightTrigger(self):
return self.js.get_button(2)
class XboxController(Controller):
def __init__(self, joystick):
super(XboxController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(3)
def getRightVert(self):
return self.js.get_axis(4)
def getLeftTrigger(self):
return self.js.get_axis(2)
def getRightTrigger(self):
return self.js.get_button(11)
class Ps3Controller(Controller):
#up 4 _DOWN 6 left 7 right 5 croix 14 rond 13 triangle 12
def __init__(self, joystick):
super(Ps3Controller, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(2)
def getRightVert(self):
return self.js.get_axis(3)
def getLeftTrigger(self):
# TODO: Verify
return self.js.get_button(8)
def getRightTrigger(self):
# TODO: Verify
return self.js.get_button(9)
def getUp(self):
return self.js.get_button(4)
def getDown(self):
return self.js.get_button(6)
def getLeft(self):
return self.js.get_button(7)
def getRight(self):
return self.js.get_button(5)
def getFire1(self):
return self.js.get_button(14)
def getFire2(self):
return self.js.get_button(13)
class MySaitekController(Controller):
def __init__(self, joystick):
super(MySaitekController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(3)
def getRightVert(self):
return self.js.get_axis(2)
def getLeftTrigger(self):
return self.js.get_button(6)
def getRightTrigger(self):
return self.js.get_button(7)
class MyThrustController(Controller):
def __init__(self, joystick):
super(MyThrustController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(2)
def getRightVert(self):
return self.js.get_axis(3)
def getLeftTrigger(self):
return self.js.get_button(5)
def getRightTrigger(self):
return self.js.get_button(7)
class CSLController(Controller):
def __init__(self, joystick):
super(CSLController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(2)
def getLeftVert(self):
return self.js.get_axis(3)
def getRightHori(self):
return self.js.get_axis(0)
def getRightVert(self):
return self.js.get_axis(1)
def getLeftTrigger(self):
return self.js.get_button(6)
def getRightTrigger(self):
return self.js.get_button(7)
def getFire1(self):
return self.js.get_button(2)
def getFire2(self):
return self.js.get_button(1)
class USBController(Controller):
# my USB Joystick
#up axis 0 -1 DOWN axis 0 1 left axis 1 1 right axis 1 -1 bouton gauche 10 bouton droite 9
def __init__(self, joystick):
super(USBController, self).__init__(joystick)
def getUp(self):
if self.js.get_axis(0) == -1:
return 1
else:
return 0
def getDown(self):
if self.js.get_axis(0) > 0.9:
return 1
else:
return 0
def getLeft(self):
if self.js.get_axis(1) == 1:
return 1
else:
return 0
def getRight(self):
if self.js.get_axis(1) == -1:
return 1
else:
return 0
def getLeftTrigger(self):
return self.js.get_button(10)
def getRightTrigger(self):
return self.js.get_button(9)
def getFire1(self):
if self.js.get_button(10) == 1:
print ("fire 1")
return self.js.get_button(10)
def getFire2(self):
if self.js.get_button(9) == 1:
print ("fire 2")
return self.js.get_button(9)

1
plugins/VJing/poses Symbolic link
View File

@ -0,0 +1 @@
../../../LJay/poses

598
plugins/VJing/poses.py Normal file
View File

@ -0,0 +1,598 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
Laser Jaying
LICENCE : CC
Sam Neurohack, Loloster,
Openpose json files animations
Set for amiral castle :
Curve 0 : Mapping
Curve 1 : Pose align on Laser 0 for the moment
Curve 2 : Faces
Curve 3 : Dancers
'''
import math
import gstt
from globalVars import *
import bhoroscp
import colorify
import numpy as np
import pdb
import time
from datetime import datetime
import settings
# For Mapping()
# dedicated settings handler is in settings.py
import pygame
f_sine = 0
# Curve 0
# Edit shape mode / Run Mode
def MappingConf(section):
global mouse_prev, sections
print ""
print "For Mapping(), reading Architecture Points"
gstt.EditStep = 0
gstt.CurrentWindow = -1
gstt.CurrentCorner = 0
gstt.CurrentSection = section
mouse_prev = ((405, 325), (0, 0, 0))
# Get all shapes points (="corners") for the given section of the conf file -> gstt.Windows
gstt.Windows = []
sections = settings.MappingSections()
print ""
#print "Sections : ", sections
print "Reading Section : ", sections[gstt.CurrentSection]
gstt.Laser = settings.MappingRead([sections[gstt.CurrentSection],'laser'])
print "Laser : ", gstt.Laser
gstt.simuPL = gstt.Laser
for Window in xrange(settings.Mapping(sections[gstt.CurrentSection])-1):
print "Reading option : ", str(Window)
shape = [sections[gstt.CurrentSection], str(Window)]
WindowPoints = settings.MappingRead(shape)
gstt.Windows.append(WindowPoints)
print "Section points : " ,gstt.Windows
# section 0 is "General", then first screen shapes in section 1
# Todo : Should search automatically first screen in settings file sections.
# MappingConf(1) should be call only if curve 0 is selected
def Mapping(fwork, keystates, keystates_prev):
global mouse_prev, sections
PL = gstt.Laser
dots = []
#switch to edit mode Key E ?
if keystates[pygame.K_e] and not keystates_prev[pygame.K_e] and gstt.EditStep == 0:
print "Switching to Edit Mode"
gstt.EditStep = 1
gstt.CurrentWindow = 0
gstt.CurrentCorner = 0
# Back to normal if ENTER key is pressed ?
if keystates[pygame.K_RETURN] and gstt.EditStep == 1:
print "Switching to Run Mode"
gstt.EditStep =0
# EDIT MODE : cycle windows if press e key to adjust corner position
# Escape edit mode with enter key
if gstt.EditStep >0:
dots = []
CurrentWindowPoints = gstt.Windows[gstt.CurrentWindow]
# Draw all windows points or "corners"
for corner in xrange(len(CurrentWindowPoints)):
dots.append(proj(int(CurrentWindowPoints[corner][0]),int(CurrentWindowPoints[corner][1]),0))
fwork.PolyLineOneColor( dots, c=colorify.rgb2hex(gstt.color), PL = PL, closed = False )
# Left mouse is clicked, modify current Corner coordinate
if gstt.mouse[1][0] == mouse_prev[1][0] and mouse_prev[1][0] == 1:
deltax = gstt.mouse[0][0]-mouse_prev[0][0]
deltay = gstt.mouse[0][1]-mouse_prev[0][1]
CurrentWindowPoints[gstt.CurrentCorner][0] += (deltax *2)
CurrentWindowPoints[gstt.CurrentCorner][1] -= (deltay * 2)
# Change corner if Z key is pressed.
if keystates[pygame.K_z] and not keystates_prev[pygame.K_z]:
if gstt.CurrentCorner < settings.Mapping(sections[gstt.CurrentSection]) - 1:
gstt.CurrentCorner += 1
print "Corner : ", gstt.CurrentCorner
# Press E inside Edit mode : Next window
if keystates[pygame.K_e] and not keystates_prev[pygame.K_e]:
# Save current Window and switch to the next one.
if gstt.CurrentWindow < settings.Mapping(sections[gstt.CurrentSection]) -1:
print "saving "
settings.MappingWrite(sections,str(gstt.CurrentWindow),CurrentWindowPoints)
gstt.CurrentWindow += 1
gstt.CurrentCorner = -1
if gstt.CurrentWindow == settings.Mapping(sections[gstt.CurrentSection]) -1:
gstt.EditStep == 0
gstt.CurrentWindow = 0
print "Now Editing window ", gstt.CurrentWindow
mouse_prev = gstt.mouse
gstt.PL[PL] = fwork.LinesPL(PL)
# Press A : Next section ?
if keystates[pygame.K_a] and not keystates_prev[pygame.K_a]:
print "current section : ", gstt.CurrentSection
if gstt.CurrentSection < len(sections)-1:
gstt.CurrentSection += 1
print "Next section name is ", sections[gstt.CurrentSection]
if "screen" in sections[gstt.CurrentSection]:
print ""
print "switching to section ", gstt.CurrentSection, " ", sections[gstt.CurrentSection]
MappingConf(gstt.CurrentSection)
else:
gstt.CurrentSection = -1
# RUN MODE
if gstt.EditStep == 0:
# Add all windows to PL for display
for Window in gstt.Windows:
dots = []
for corner in xrange(len(Window)):
#print "Editing : ", WindowPoints[corner]
#print Window[corner][0]
dots.append(proj(int(Window[corner][0]),int(Window[corner][1]),0))
fwork.PolyLineOneColor( dots, c=colorify.rgb2hex(gstt.color), PL = PL, closed = False )
gstt.PL[PL] = fwork.LinesPL(PL)
# Curve 1 : generic pose animations
import json
gstt.CurrentPose = 1
'''
# get absolute body position points
def getCOCO(pose_json,pose_points):
dots = []
for dot in pose_points:
if len(pose_json['part_candidates'][0][str(dot)]) != 0:
dots.append((pose_json['part_candidates'][0][str(dot)][0], pose_json['part_candidates'][0][str(dot)][1]))
return dots
# get relative (-1 0 1) body position points. a position -1, -1 means doesn't exist
def getBODY(pose_json,pose_points):
dots = []
for dot in pose_points:
#print pose_points
if len(pose_json['people'][0]['pose_keypoints_2d']) != 0:
#print "people 0"
if pose_json['people'][0]['pose_keypoints_2d'][dot * 3] != -1 and pose_json['people'][0]['pose_keypoints_2d'][(dot * 3)+1] != -1:
dots.append((pose_json['people'][0]['pose_keypoints_2d'][dot * 3], pose_json['people'][0]['pose_keypoints_2d'][(dot * 3)+1]))
#if len(pose_json['people']) != 1:
#print "people1"
#print "people 1", pose_json['people'][1]['pose_keypoints_2d']
#print len(pose_json['people'])
return dots
# get absolute face position points
def getFACE(pose_json,pose_points):
dots = []
for dot in pose_points:
if len(pose_json['people'][0]['face_keypoints_2d']) != 0:
print "people 0"
if pose_json['people'][0]['face_keypoints_2d'][dot * 3] != -1 and pose_json['people'][0]['face_keypoints_2d'][(dot * 3)+1] != -1:
dots.append((pose_json['people'][0]['face_keypoints_2d'][dot * 3], pose_json['people'][0]['face_keypoints_2d'][(dot * 3)+1]))
if len(pose_json['people']) != 1:
print "people 1"
#print "people 1", pose_json['people'][1]['face_keypoints_2d']
return dots
# Body parts
def bodyCOCO(pose_json):
pose_points = [10,9,8,1,11,12,13]
return getBODY(pose_json,pose_points)
def armCOCO(pose_json):
pose_points = [7,6,5,1,2,3,4]
return getBODY(pose_json,pose_points)
def headCOCO(pose_json):
pose_points = [1,0]
return getBODY(pose_json,pose_points)
# Face keypoints
def face(pose_json):
pose_points = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
return getFACE(pose_json,pose_points)
def browL(pose_json):
pose_points = [26,25,24,23,22]
return getFACE(pose_json,pose_points)
def browR(pose_json):
pose_points = [21,20,19,18,17]
return getFACE(pose_json,pose_points)
def eyeR(pose_json):
pose_points = [36,37,38,39,40,41,36]
return getFACE(pose_json,pose_points)
def eyeL(pose_json):
pose_points = [42,43,44,45,46,47,42]
return getFACE(pose_json,pose_points)
def nose(pose_json):
pose_points = [27,28,29,30]
return getFACE(pose_json,pose_points)
def mouth(pose_json):
pose_points = [48,59,58,57,56,55,54,53,52,51,50,49,48,60,67,66,65,64,63,62,61,60]
return getFACE(pose_json,pose_points)
# best order face : face browL browr eyeR eyeL nose mouth
'''
# get absolute body position points
def getCOCO(pose_json,pose_points, people):
dots = []
for dot in pose_points:
if len(pose_json['part_candidates'][people][str(dot)]) != 0:
dots.append((pose_json['part_candidates'][people][str(dot)][0], pose_json['part_candidates'][people][str(dot)][1]))
return dots
# get relative (-1 0 1) body position points. a position -1, -1 means doesn't exist
def getBODY(pose_json,pose_points, people):
dots = []
for dot in pose_points:
#print pose_points
if len(pose_json['people'][people]['pose_keypoints_2d']) != 0:
#print "people 0"
if pose_json['people'][people]['pose_keypoints_2d'][dot * 3] != -1 and pose_json['people'][people]['pose_keypoints_2d'][(dot * 3)+1] != -1:
dots.append((pose_json['people'][people]['pose_keypoints_2d'][dot * 3], pose_json['people'][people]['pose_keypoints_2d'][(dot * 3)+1]))
return dots
# get absolute face position points
def getFACE(pose_json,pose_points, people):
dots = []
for dot in pose_points:
if len(pose_json['people'][people]['face_keypoints_2d']) != 0:
#print "people 0"
if pose_json['people'][people]['face_keypoints_2d'][dot * 3] != -1 and pose_json['people'][people]['face_keypoints_2d'][(dot * 3)+1] != -1:
dots.append((pose_json['people'][people]['face_keypoints_2d'][dot * 3], pose_json['people'][people]['face_keypoints_2d'][(dot * 3)+1]))
'''
if len(pose_json['people']) > 1:
print len(pose_json['people'])
print "people 1 face ", pose_json['people'][1]['face_keypoints_2d']
'''
return dots
# Body parts
def bodyCOCO(pose_json, people):
pose_points = [10,9,8,1,11,12,13]
return getBODY(pose_json,pose_points, people)
def armCOCO(pose_json, people):
pose_points = [7,6,5,1,2,3,4]
return getBODY(pose_json,pose_points, people)
def headCOCO(pose_json, people):
pose_points = [1,0]
return getBODY(pose_json,pose_points, people)
# Face keypoints
def face(pose_json, people):
pose_points = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
return getFACE(pose_json,pose_points, people)
def browL(pose_json, people):
pose_points = [26,25,24,23,22]
return getFACE(pose_json,pose_points, people)
def browR(pose_json, people):
pose_points = [21,20,19,18,17]
return getFACE(pose_json,pose_points, people)
def eyeR(pose_json, people):
pose_points = [36,37,38,39,40,41,36]
return getFACE(pose_json,pose_points, people)
def eyeL(pose_json, people):
pose_points = [42,43,44,45,46,47,42]
return getFACE(pose_json,pose_points, people)
def nose(pose_json, people):
pose_points = [27,28,29,30]
return getFACE(pose_json,pose_points, people)
def mouth(pose_json, people):
pose_points = [48,59,58,57,56,55,54,53,52,51,50,49,48,60,67,66,65,64,63,62,61,60]
return getFACE(pose_json,pose_points, people)
import os
# Get frame number for pose path describe in gstt.PoseDir
def lengthPOSE(pose_dir):
if gstt.debug > 0:
print "Check directory ",'poses/' + pose_dir + '/'
numfiles = sum(1 for f in os.listdir('poses/' + pose_dir + '/') if os.path.isfile(os.path.join('poses/' + pose_dir + '/', f)) and f[0] != '.')
if gstt.debug > 0:
print "Pose : ", pose_dir, numfiles, "images"
return numfiles
def preparePOSE():
# anim format (name, xpos,ypos, resize, currentframe, totalframe, count, speed)
# total frames is fetched from directory file count
anims1 = [['sky',50,100,300,0,0,0,1],['2dancer1', 400,100, 300,0,0,0,1],['1dancer', 400,100, 300,0,0,0,1],['window1',100,100,300,0,0,0,1]]
anims2 = [['window1', 400,200, 300,0,0,0,1],['2dancer1',100,200,300,0,0,0,1]]
for anim in anims1:
anim[5]= lengthPOSE(anim[0])
gstt.anims0 = anims1
# display n pose animations on Laser 0
def Pose(fwork):
for anim in gstt.anims0:
PL = 0
dots = []
print anim, anim[5]
# repeat anim[7] time the same frame
anim[6] +=1
if anim[6] == anim[7]:
anim[6] = 0
# increase current frame and compare to total frame
anim[4] += 1
if anim[4] == anim[5]:
anim[4] = 0
posename = 'poses/' + anim[0] + '/' + anim[0] +'-'+str("%05d"%anim[4])+'.json'
posefile = open(posename , 'r')
posedatas = posefile.read()
pose_json = json.loads(posedatas)
for people in range(len(pose_json['people'])):
fwork.rPolyLineOneColor(bodyCOCO(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(armCOCO(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(headCOCO(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
# Face
'''
#fwork.rPolyLineOneColor(face(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(browL(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(browR(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(eyeR(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(eyeL(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(nose(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(mouth(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
'''
gstt.PL[PL] = fwork.LinesPL(PL)
time.sleep(0.02)
# decrease current frame
if gstt.keystates[pygame.K_w]: # and not gstt.keystates_prev[pygame.K_w]:
gstt.CurrentPose -= 1
if gstt.CurrentPose < 2:
gstt.CurrentPose = gstt.numfiles -1
#time.sleep(0.033)
print "Frame : ",gstt.CurrentPose
# increaser current frame
if gstt.keystates[pygame.K_x]: # and not gstt.keystates_prev[pygame.K_x]:
gstt.CurrentPose += 1
if gstt.CurrentPose > gstt.numfiles -1:
gstt.CurrentPose = 1
#time.sleep(0.033)
print "Frame : ",gstt.CurrentPose
# Curve 2 Faces
import json
gstt.CurrentPose = 1
def prepareFACES():
# anim format (name, xpos,ypos, resize, currentframe, totalframe, count, speed)
# total frame is fetched from directory file count
gstt.anims[0] = [['detroit1', 300,300, 100,0,0,0,1]]
gstt.anims[1] = [['detroit1', 400,200, 200,0,0,0,1]]
gstt.anims[2] = [['detroit1', 500,200, 300,0,0,0,1]]
'''
# read anims number of frames from disk.
for anim in range(len(gstt.anims0)):
gstt.anims0[anim][5]= lengthPOSE(gstt.anims0[anim][0])
for anim in range(len(gstt.anims1)):
gstt.anims1[anim][5]= lengthPOSE(gstt.anims1[anim][0])
for anim in range(len(gstt.anims2)):
gstt.anims2[anim][5]= lengthPOSE(gstt.anims2[anim][0])
'''
for laseranims in range(3):
print laseranims
for anim in range(len(gstt.anims[laseranims])):
gstt.anims[laseranims][anim][5]= lengthPOSE(gstt.anims[laseranims][anim][0])
# display the face animation describe in gstt.PoseDir
def Faces(fwork):
for laseranims in range(3):
for anim in gstt.anims[laseranims]:
PL = laseranims
#print PL, anim
dots = []
#print anim, anim[5]
# repeat anim[7] time the same frame
anim[6] +=1
if anim[6] == anim[7]:
anim[6] = 0
# increase current frame and compare to total frame
anim[4] += 1
if anim[4] == anim[5]:
anim[4] = 0
posename = 'poses/' + anim[0] + '/' + anim[0] +'-'+str("%05d"%anim[4])+'.json'
posefile = open(posename , 'r')
posedatas = posefile.read()
pose_json = json.loads(posedatas)
# Face
for people in range(len(pose_json['people'])):
#fwork.rPolyLineOneColor(face(pose), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(browL(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(browR(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(eyeR(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(eyeL(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(nose(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(mouth(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
gstt.PL[PL] = fwork.LinesPL(PL)
time.sleep(0.02)
# Curve 3
# Dancers
import json
gstt.CurrentPose = 1
def prepareDANCERS():
# anim format (name, xpos,ypos, resize, currentframe, totalframe, count, speed)
# total frame is fetched from directory file count
gstt.anims[0] = [['1dancer',500,200,300,0,0,0,10]]
gstt.anims[1] = [['2dancer1',500,200,300,0,0,0,10]]
gstt.anims[2] = [['window1',500,200,300,0,0,0,10]]
#gstt.anims[1] = [['2dancer1',100,200,300,0,0,0,10]]
#gstt.anims[2] = [['window1',400,200, 300,0,0,0,10]]
# read anims number of frames from disk.
print gstt.anims
for laseranims in range(3):
print laseranims
for anim in range(len(gstt.anims[laseranims])):
gstt.anims[laseranims][anim][5]= lengthPOSE(gstt.anims[laseranims][anim][0])
# display the pose animation describe in gstt.PoseDir
def Dancers(fwork):
for laseranims in range(3):
for anim in gstt.anims[laseranims]:
PL = laseranims
#print PL, anim
dots = []
#print anim, anim[5]
# repeat anim[7] time the same frame
anim[6] +=1
if anim[6] == anim[7]:
anim[6] = 0
# increase current frame and compare to total frame
anim[4] += 1
if anim[4] == anim[5]:
anim[4] = 0
#bhorosc.sendresol("/layer1/clip1/connect",1)
#bhorosc.sendresol("/layer1/clip1/connect",0)
posename = 'poses/' + anim[0] + '/' + anim[0] +'-'+str("%05d"%anim[4])+'.json'
posefile = open(posename , 'r')
posedatas = posefile.read()
pose_json = json.loads(posedatas)
for people in range(len(pose_json['people'])):
fwork.rPolyLineOneColor(bodyCOCO(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(armCOCO(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(browL(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(browR(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(eyeR(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(eyeL(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(nose(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(mouth(pose_json, people), c=colorify.rgb2hex(gstt.color), PL = laseranims, closed = False,xpos = anim[1], ypos = anim[2], resize = anim[3])
gstt.PL[PL] = fwork.LinesPL(PL)
'''
fwork.rPolyLineOneColor(bodyCOCO(pose_json), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(armCOCO(pose_json), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
fwork.rPolyLineOneColor(headCOCO(pose_json), c=colorify.rgb2hex(gstt.color), PL = 0, closed = False, xpos = anim[1], ypos = anim[2], resize = anim[3])
gstt.PL[PL] = fwork.LinesPL(PL)
'''

154
plugins/livewords.py Normal file
View File

@ -0,0 +1,154 @@
# coding=UTF-8
'''
Live words on different lasers
LICENCE : CC
'''
import redis
import lj3
import sys,time
import argparse
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
#from osc4py3 import oscmethod as osm
from osc4py3.oscmethod import *
duration = 300
OSCinPort = 8006
Word0 = "0"
Word1 = "1"
Word2 = "2"
Word3 = "3"
'''
is_py2 = sys.version[0] == '2'
if is_py2:
from Queue import Queue
else:
from queue import Queue
'''
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Text Cycling for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-v","--verbose",help="Verbosity level (0 by default)",type=int)
args = argsparser.parse_args()
if args.client:
ljclient = args.client
else:
ljclient = 0
# Redis Computer IP
if args.redisIP != None:
redisIP = args.redisIP
else:
redisIP = '127.0.0.1'
if args.verbose:
debug = args.verbose
else:
debug = 0
lj3.Config(redisIP,ljclient)
#r = redis.StrictRedis(host=redisIP, port=6379, db=0)
def OSCword0(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
Word0 = value
def OSCword1(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
Word1 = value
def OSCword2(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
Word3 = value
def OSCword3(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
Word3 = value
def OSCljclient(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /words/ljclient with value", value)
ljclient = value
lj3.LjClient(ljclient)
def WebStatus(message):
lj3.Send("/status",message)
def Run():
WebStatus("Load Words")
# OSC Server callbacks
print("Starting OSC at 127.0.0.1 port",OSCinPort,"...")
osc_startup()
osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/words/0*", OSCword0)
osc_method("/words/1*", OSCword1)
osc_method("/words/2*", OSCword2)
osc_method("/words/3*", OSCword3)
osc_method("/ping*", lj3.OSCping)
osc_method("/words/ljclient", OSCljclient)
color = lj3.rgb2int(255,255,255)
WebStatus("Words ready.")
try:
while 1:
lj3.OSCframe()
lj3.Text(Word0, color, PL = 0, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj3.DrawPL(0)
lj3.Text(Word1, color, PL = 1, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj3.DrawPL(1)
lj3.Text(Word2, color, PL = 2, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj3.DrawPL(2)
lj3.Text(Word3, color, PL = 3, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj3.DrawPL(3)
time.sleep(0.01)
except KeyboardInterrupt:
pass
# Gently stop on CTRL C
finally:
WebStatus("Words Exit")
print("Stopping OSC...")
lj3.OSCstop()
print ("Words Stopped.")
Run()

620
plugins/lj3.py Normal file
View File

@ -0,0 +1,620 @@
# coding=UTF-8
'''
LJ v0.8.1 in python3
Some LJ functions useful for python clients (was framy.py)
OSC functions commented, waiting working on OSC in python3
Config(redisIP, client number)
PolyLineOneColor
rPolyLineOneColor
Text(word, color, PL, xpos, ypos, resize, rotx, roty, rotz) : Display a word
Send(adress,message) : remote control. See commands.py
WebStatus(message) : display message on webui
DrawPL(point list number) : once you stacked all wanted elements, like 2 polylines, send them to lasers.
rgb2int(r,g,b)
OSCstart(): Start the OSC system.
OSCframe():
OSCstop(): Properly close the OSC system
OSCping(value): Answer to LJ pings
setup_controls(joystick)
XboxController : getLeftHori, getLeftVert, getRightHori, getRightVert, getLeftTrigger, getRightTrigger
Ps3Controller : getLeftHori, getLeftVert, getRightHori, getRightVert, getLeftTrigger, getRightTrigger, getUp, getDown, getLeft, getRight, getFire1, getFire2(self):
MySaitekController : getLeftHori,getLeftVert, getRightHori,getRightVert, getLeftTrigger,getRightTrigger
MyThrustController : getLeftHori, getLeftVert, getRightHori, getRightVert, getLeftTrigger, getRightTrigger
CSLController : getLeftHori,getLeftVert,getRightHori, getRightVert,getLeftTrigger,getRightTrigger,getFire1,getFire2
my USB Joystick : getUp,getDown,getLeft,getRight,etLeftTrigger, getRightTrigger,getFire1, getFire2
LICENCE : CC
Sam Neurohack
'''
import math
import redis
# Import needed modules from osc4py3
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
#from osc4py3 import oscmethod as osm
from osc4py3.oscmethod import *
redisIP = '127.0.0.1'
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = 0
point_list = []
pl = [[],[],[],[]]
#
# OSC interaction with LJ
#
def OSCstart():
# Start the system.
osc_startup()
#osc_udp_client(redisIP, 8002, "LJ 8002")
def OSCframe():
#print("OSCprocess")
osc_process()
# Properly close the system. Todo
def OSCstop():
osc_terminate()
# Answer to LJ pings
def OSCping(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /ping with value", value)
Send("/pong",value)
def Send(oscaddress,oscargs=''):
try:
msg = oscbuildparse.OSCMessage(oscaddress, None, [oscargs])
osc_send(msg, "LJ 8002")
OSCframe()
except:
print ('Connection to LJ refused : died ?')
pass
'''
def handlerfunction(s, x, y):
# Will receive message data unpacked in s, x, y
pass
def handlerfunction2(address, s, x, y):
# Will receive message address, and message data flattened in s, x, y
pass
# Make server channels to receive packets.
osc_udp_server("127.0.0.1", 3721, "localhost")
osc_udp_server("0.0.0.0", 3724, "anotherserver")
'''
ASCII_GRAPHICS = [
# caracteres corrects
[(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)], #0
[(-20,30), (0,-30), (-20,30)], #1
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #2
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #3
[(30,10), (-30,10), (0,-30), (0,30)], #4
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #5
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #6
[(-30,-30), (30,-30), (-30,30)], #7
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #8
[(30,0), (-30,0), (-30,-10), (0,-30), (30,-30), (30,10), (0,30), (-30,30)], #9
# caracteres a implementer
[(-30,10), (30,-10), (30,10), (0,30), (-30,10), (-30,-10), (0,-30), (30,-10)], #:
[(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #;
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #<
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #=
[(30,10), (-30,10), (0,-30), (0,30)], #>
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #?
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #@
# Caracteres corrects
[(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A
[(-30,30), (-30,-30), (30,-30), (30,30), (30,0), (-30,0)], #A
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30), (-30,0), (30,0)], #B
[(30,30), (-30,30), (-30,-30), (30,-30)], #C
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30)], #D
[(30,30), (-30,30), (-30,-0), (30,0), (-30,0), (-30,-30), (30,-30)], #E
[(-30,30), (-30,-0), (30,0), (-30,0), (-30,-30), (30,-30)], #F
[(0,0), (30,0), (30,30), (-30,30), (-30,-30),(30,-30)], #G
[(-30,-30), (-30,30), (-30,0), (30,0), (30,30), (30,-30)], #H
[(0,30), (0,-30)], #I
[(-30,30), (0,-30), (0,-30), (-30,-30), (30,-30)], #J
[(-30,-30), (-30,30), (-30,0), (30,-30), (-30,0), (30,30)], #K
[(30,30), (-30,30), (-30,-30)], #L
[(-30,30), (-30,-30), (0,0), (30,-30), (30,30)], #M
[(-30,30), (-30,-30), (30,30), (30,-30)], #N
[(-30,30), (-30,-30), (30,-30), (30,30), (-30,30)], #O
[(-30,0), (30,0), (30,-30), (-30,-30), (-30,30)], #P
[(30,30), (30,-30), (-30,-30), (-30,30), (30,30),(35,35)], #Q
[(-30,30), (-30,-30), (30,-30), (30,0), (-30,0), (30,30)], #R
[(30,-30), (-30,-30), (-30,0), (30,0), (30,30), (-30,30)], #S
[(0,30), (0,-30), (-30,-30), (30,-30)], #T
[(-30,-30), (-30,30), (30,30), (30,-30)], #U
[(-30,-30), (0,30), (30,-30)], #V
[(-30,-30), (-30,30), (0,0), (30,30), (30,-30)], #W
[(-30,30), (30,-30)], [(-30,-30), (30,30)], #X
[(0,30), (0,0), (30,-30), (0,0), (-30,-30)], #Y
[(30,30), (-30,30), (30,-30), (-30,-30)], #Z
# A implementer
[(-30,-10), (0,-30), (0,30)], [(-30,30), (30,30)], #[
[(-30,-10), (0,-30), (30,-10), (30,0), (-30,30), (30,30)], #\
[(-30,-30), (0,-30), (30,-10), (0,0), (30,10), (0,30), (-30,30)], #]
[(30,10), (-30,10), (0,-30), (0,30)], #^
[(30,-30), (-30,-30), (-30,0), (0,0), (30,10), (0,30), (-30,30)], #_
[(30,-30), (0,-30), (-30,-10), (-30,30), (0,30), (30,10), (30,0), (-30,0)], #`
# Implementé
[(-20,20), (-20,-20), (20,-20), (20,20), (20,0), (-20,0)], #a
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20), (-20,0), (20,0)], #b
[(20,20), (-20,20), (-20,-20), (20,-20)], #c
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20)], #d
[(20,20), (-20,20), (-20,-0), (20,0), (-20,0), (-20,-20), (20,-20)], #e
[(-20,20), (-20,-0), (20,0), (-20,0), (-20,-20), (20,-20)], #f
[(0,0), (20,0), (20,20), (-20,20), (-20,-20),(20,-20)], #g
[(-20,-20), (-20,20), (-20,0), (20,0), (20,20), (20,-20)], #H
[(0,20), (0,-20)], #I
[(-20,20), (0,-20), (0,-20), (-20,-20), (20,-20)], #J
[(-20,-20), (-20,20), (-20,0), (20,-20), (-20,0), (20,20)], #K
[(20,20), (-20,20), (-20,-20)], #L
[(-20,20), (-20,-20), (0,0), (20,-20), (20,20)], #M
[(-20,20), (-20,-20), (20,20), (20,-20)], #N
[(-20,20), (-20,-20), (20,-20), (20,20), (-20,20)], #O
[(-20,0), (20,0), (20,-20), (-20,-20), (-20,20)], #P
[(20,20), (20,-20), (-20,-20), (-20,20), (20,20),(25,25)], #Q
[(-20,20), (-20,-20), (20,-20), (20,0), (-20,0), (20,20)], #R
[(20,-20), (-20,-20), (-20,0), (20,0), (20,20), (-20,20)], #S
[(0,20), (0,-20), (-20,-20), (20,-20)], #T
[(-20,-20), (-20,20), (20,20), (20,-20)], #U
[(-20,-20), (0,20), (20,-20)], #V
[(-20,-20), (-20,20), (0,0), (20,20), (20,-20)], #W
[(-20,20), (20,-20)], [(-20,-20), (20,20)], #X
[(0,20), (0,0), (20,-20), (0,0), (-20,-20)], #Y
[(20,20), (-20,20), (20,-20), (-20,-20)], #Z
[(-2,15), (2,15)] # Point a la place de {
]
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
def Config(redisIP,client):
global ClientNumber
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = client
osc_udp_client(redisIP, 8002, "LJ 8002")
def LjClient(client):
global ClientNumber
ClientNumber = client
def LineTo(xy, c, PL):
pl[PL].append((xy + (c,)))
def Line(xy1, xy2, c, PL):
LineTo(xy1, 0, PL)
LineTo(xy2, c , PL)
def PolyLineOneColor(xy_list, c, PL , closed ):
#print "--"
#print "c",c
#print "xy_list",xy_list
#print "--"
xy0 = None
for xy in xy_list:
if xy0 is None:
xy0 = xy
#print "xy0:",xy0
LineTo(xy0,0, PL)
LineTo(xy0,c, PL)
else:
#print "xy:",xy
LineTo(xy,c, PL)
if closed:
LineTo(xy0,c, PL)
# Computing points coordinates for rPolyline function from 3D and around 0,0 to pygame coordinates
def Pointransf(xy, xpos = 0, ypos =0, resize =1, rotx =0, roty =0 , rotz=0):
x = xy[0] * resize
y = xy[1] * resize
z = 0
rad = rotx * math.pi / 180
cosaX = math.cos(rad)
sinaX = math.sin(rad)
y2 = y
y = y2 * cosaX - z * sinaX
z = y2 * sinaX + z * cosaX
rad = roty * math.pi / 180
cosaY = math.cos(rad)
sinaY = math.sin(rad)
z2 = z
z = z2 * cosaY - x * sinaY
x = z2 * sinaY + x * cosaY
rad = rotz * math.pi / 180
cosZ = math.cos(rad)
sinZ = math.sin(rad)
x2 = x
x = x2 * cosZ - y * sinZ
y = x2 * sinZ + y * cosZ
#print xy, (x + xpos,y+ ypos)
return (x + xpos,y+ ypos)
'''
to understand why it get negative Y
# 3D to 2D projection
factor = 4 * gstt.cc[22] / ((gstt.cc[21] * 8) + z)
print xy, (x * factor + xpos, - y * factor + ypos )
return (x * factor + xpos, - y * factor + ypos )
'''
# Send 2D point list around 0,0 with 3D rotation resizing and reposition around xpos ypos
#def rPolyLineOneColor(self, xy_list, c, PL , closed, xpos = 0, ypos =0, resize =1, rotx =0, roty =0 , rotz=0):
def rPolyLineOneColor(xy_list, c, PL , closed, xpos = 0, ypos =0, resize =0.7, rotx =0, roty =0 , rotz=0):
xy0 = None
for xy in xy_list:
if xy0 is None:
xy0 = xy
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),0, PL)
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),c, PL)
else:
LineTo(Pointransf(xy, xpos, ypos, resize, rotx, roty, rotz),c, PL)
if closed:
LineTo(Pointransf(xy0, xpos, ypos, resize, rotx, roty, rotz),c, PL)
def LinesPL(PL):
print ("Stupido !! your code is to old : use DrawPL() instead of LinesPL()")
DrawPL(PL)
def DrawPL(PL):
#print '/pl/0/'+str(PL), str(pl[PL])
if r.set('/pl/'+str(ClientNumber)+'/'+str(PL), str(pl[PL])) == True:
pl[PL] = []
return True
else:
return False
def ResetPL(self, PL):
pl[PL] = []
def DigitsDots(number,color):
dots =[]
for dot in ASCII_GRAPHICS[number]:
#print dot
dots.append((gstt.xy_center[0]+dot[0],gstt.xy_center[1]+dot[1],color))
#self.point_list.append((xy + (c,)))
return dots
def CharDots(char,color):
dots =[]
for dot in ASCII_GRAPHICS[ord(char)-46]:
dots.append((dot[0],dot[1],color))
return dots
def Text(message,c, PL, xpos, ypos, resize, rotx, roty, rotz):
dots =[]
l = len(message)
i= 0
#print message
for ch in message:
#print ""
# texte centre en x automatiquement selon le nombre de lettres l
x_offset = 26 * (- (0.9*l) + 3*i)
#print i,x_offset
# if digit
if ord(ch)<58:
char_pl_list = ASCII_GRAPHICS[ord(ch) - 48]
else:
char_pl_list = ASCII_GRAPHICS[ord(ch) - 46 ]
char_draw = []
#dots.append((char_pl_list[0][0] + x_offset,char_pl_list[0][1],0))
for xy in char_pl_list:
char_draw.append((xy[0] + x_offset,xy[1],c))
i +=1
#print ch,char_pl_list,char_draw
rPolyLineOneColor(char_draw, c, PL , False, xpos, ypos, resize, rotx, roty, rotz)
#print ("laser",PL,"message",message)
#dots.append(char_draw)
import re
def setup_controls(joystick):
"""
Joystick wrapper.
"""
if re.search('playstation', joystick.get_name(), re.I):
return Ps3Controller(joystick)
elif re.search('X-box', joystick.get_name(), re.I):
return XboxController(joystick)
elif re.search('Saitek', joystick.get_name(), re.I):
return MySaitekController(joystick)
elif re.search('Thrustmaster dual analog 3.2', joystick.get_name(), re.I):
return MyThrustController(joystick)
elif re.search('2n1 USB', joystick.get_name(), re.I):
return CSLController(joystick)
elif re.search('Joystick', joystick.get_name(), re.I):
return USBController(joystick)
return Controller(joystick)
class Controller(object):
def __init__(self, joystick):
"""Pass a PyGame joystick instance."""
self.js = joystick
def getLeftHori(self):
return self.js.get_axis(2)
def getLeftVert(self):
return self.js.get_axis(3)
def getRightHori(self):
return self.js.get_axis(0)
def getRightVert(self):
return self.js.get_axis(1)
def getLeftTrigger(self):
return self.js.get_button(9)
def getRightTrigger(self):
return self.js.get_button(2)
class XboxController(Controller):
def __init__(self, joystick):
super(XboxController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(3)
def getRightVert(self):
return self.js.get_axis(4)
def getLeftTrigger(self):
return self.js.get_axis(2)
def getRightTrigger(self):
return self.js.get_button(11)
class Ps3Controller(Controller):
#up 4 _DOWN 6 left 7 right 5 croix 14 rond 13 triangle 12
def __init__(self, joystick):
super(Ps3Controller, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(2)
def getRightVert(self):
return self.js.get_axis(3)
def getLeftTrigger(self):
# TODO: Verify
return self.js.get_button(8)
def getRightTrigger(self):
# TODO: Verify
return self.js.get_button(9)
def getUp(self):
return self.js.get_button(4)
def getDown(self):
return self.js.get_button(6)
def getLeft(self):
return self.js.get_button(7)
def getRight(self):
return self.js.get_button(5)
def getFire1(self):
return self.js.get_button(14)
def getFire2(self):
return self.js.get_button(13)
class MySaitekController(Controller):
def __init__(self, joystick):
super(MySaitekController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(3)
def getRightVert(self):
return self.js.get_axis(2)
def getLeftTrigger(self):
return self.js.get_button(6)
def getRightTrigger(self):
return self.js.get_button(7)
class MyThrustController(Controller):
def __init__(self, joystick):
super(MyThrustController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(2)
def getRightVert(self):
return self.js.get_axis(3)
def getLeftTrigger(self):
return self.js.get_button(5)
def getRightTrigger(self):
return self.js.get_button(7)
class CSLController(Controller):
def __init__(self, joystick):
super(CSLController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(2)
def getLeftVert(self):
return self.js.get_axis(3)
def getRightHori(self):
return self.js.get_axis(0)
def getRightVert(self):
return self.js.get_axis(1)
def getLeftTrigger(self):
return self.js.get_button(6)
def getRightTrigger(self):
return self.js.get_button(7)
def getFire1(self):
return self.js.get_button(2)
def getFire2(self):
return self.js.get_button(1)
class USBController(Controller):
# my USB Joystick
#up axis 0 -1 DOWN axis 0 1 left axis 1 1 right axis 1 -1 bouton gauche 10 bouton droite 9
def __init__(self, joystick):
super(USBController, self).__init__(joystick)
def getUp(self):
if self.js.get_axis(0) == -1:
return 1
else:
return 0
def getDown(self):
if self.js.get_axis(0) > 0.9:
return 1
else:
return 0
def getLeft(self):
if self.js.get_axis(1) == 1:
return 1
else:
return 0
def getRight(self):
if self.js.get_axis(1) == -1:
return 1
else:
return 0
def getLeftTrigger(self):
return self.js.get_button(10)
def getRightTrigger(self):
return self.js.get_button(9)
def getFire1(self):
if self.js.get_button(10) == 1:
print ("fire 1")
return self.js.get_button(10)
def getFire2(self):
if self.js.get_button(9) == 1:
print ("fire 2")
return self.js.get_button(9)

View File

@ -0,0 +1,89 @@
AND coordinates [['343.0', '34.5'], ['343.0', '52.5'], ['350.0', '52.5'], ['350.0', '50.0'], ['353.75', '50.0'], ['353.75', '48.0'], ['2.5', '48.0'], ['2.5', '46.0'], ['13.0', '46.0'], ['13.0', '48.0'], ['16.75', '48.0'], ['16.75', '50.0'], ['20.5', '50.0'], ['25.0', '50.0'], ['25.0', '47.0'], ['30.625', '47.0'], ['30.625', '50.5'], ['37.75', '50.5'], ['37.75', '36.75'], ['30.0', '36.75'], ['30.0', '35.0'], ['21.125', '35.0'], ['21.125', '33.0'], ['10.75', '33.0'], ['10.75', '23.75'], ['12.75', '23.75'], ['12.75', '21.0'], ['2.125', '21.0'], ['2.125', '22.0'], ['1.0', '22.0'], ['1.0', '28.0'], ['0.0', '28.0'], ['0.0', '31.333333333333332'], ['356.25', '31.333333333333332'], ['356.25', '32.083333333333336'], ['352.5', '32.083333333333336'], ['352.5', '34.5']]
ANT coordinates [['140.5', '-24.0'], ['146.25', '-24.0'], ['146.25', '-25.5'], ['153.75', '-25.5'], ['153.75', '-28.833333333333332'], ['158.75', '-28.833333333333332'], ['158.75', '-30.833333333333332'], ['162.5', '-30.833333333333332'], ['162.5', '-35.0'], ['165.0', '-35.0'], ['165.0', '-38.25'], ['140.5', '-38.25'], ['140.5', '-35.25']]
APS coordinates [['205.0', '-81.5'], ['205.0', '-75.0'], ['205.0', '-70.0'], ['221.25', '-70.0'], ['255.0', '-70.0'], ['255.0', '-66.5'], ['262.5', '-66.5'], ['270.0', '-66.5'], ['270.0', '-75.0'], ['270.0', '-81.5']]
AQL coordinates [['278.75', '0.0'], ['278.75', '2.0'], ['283.0', '2.0'], ['283.0', '6.25'], ['279.93333333333334', '6.25'], ['279.93333333333334', '12.0'], ['283.0', '12.0'], ['283.0', '18.5'], ['285.0', '18.5'], ['285.0', '16.166666666666668'], ['297.5', '16.166666666666668'], ['297.5', '15.75'], ['302.125', '15.75'], ['302.125', '8.5'], ['304.5', '8.5'], ['304.5', '2.0'], ['308.0', '2.0'], ['308.0', '0.0'], ['308.0', '-9.0'], ['300.0', '-9.0'], ['300.0', '-11.966666666666667'], ['283.0', '-11.966666666666667'], ['283.0', '-4.0'], ['278.75', '-4.0']]
AQR coordinates [['308.0', '0.0'], ['308.0', '2.0'], ['312.5', '2.0'], ['320.0', '2.0'], ['322.0', '2.0'], ['322.0', '2.75'], ['325.0', '2.75'], ['325.0', '1.75'], ['330.0', '1.75'], ['330.0', '2.0'], ['341.25', '2.0'], ['341.25', '0.0'], ['341.25', '-4.0'], ['357.5', '-4.0'], ['357.5', '-7.0'], ['357.5', '-24.5'], ['345.0', '-24.5'], ['328.0', '-24.5'], ['328.0', '-9.0'], ['320.0', '-9.0'], ['320.0', '-15.0'], ['308.0', '-15.0'], ['308.0', '-9.0']]
ARA coordinates [['246.3125', '-60.0'], ['246.3125', '-44.5'], ['267.5', '-44.5'], ['270.0', '-44.5'], ['270.0', '-57.0'], ['262.5', '-57.0'], ['262.5', '-66.5'], ['255.0', '-66.5'], ['252.5', '-66.5'], ['252.5', '-65.0'], ['251.25', '-65.0'], ['251.25', '-62.416666666666664'], ['248.75', '-62.416666666666664'], ['248.75', '-61.0'], ['246.3125', '-61.0']]
ARI coordinates [['30.0', '9.916666666666666'], ['25.0', '9.916666666666666'], ['25.0', '25.0'], ['28.75', '25.0'], ['28.75', '27.25'], ['36.25', '27.25'], ['36.25', '30.666666666666668'], ['40.75', '30.666666666666668'], ['50.5', '30.666666666666668'], ['50.5', '19.0'], ['49.25', '19.0'], ['49.25', '9.916666666666666']]
AUR coordinates [['67.5', '30.666666666666668'], ['67.5', '36.0'], ['70.375', '36.0'], ['70.375', '52.5'], ['75.0', '52.5'], ['75.0', '56.0'], ['91.5', '56.0'], ['91.5', '54.0'], ['97.5', '54.0'], ['97.5', '50.0'], ['102.0', '50.0'], ['102.0', '44.5'], ['110.5', '44.5'], ['110.5', '35.5'], ['98.0', '35.5'], ['98.0', '28.0'], ['88.25', '28.0'], ['88.25', '28.5'], ['71.25', '28.5'], ['71.25', '30.0'], ['67.5', '30.0']]
BOO coordinates [['226.25', '8.0'], ['202.5', '8.0'], ['202.5', '15.0'], ['202.5', '28.5'], ['209.375', '28.5'], ['209.375', '30.75'], ['210.5', '30.75'], ['210.5', '48.5'], ['210.5', '55.5'], ['216.25', '55.5'], ['228.75', '55.5'], ['228.75', '53.0'], ['236.25', '53.0'], ['236.25', '51.5'], ['236.25', '40.0'], ['231.5', '40.0'], ['231.5', '33.0'], ['227.75', '33.0'], ['227.75', '26.0'], ['226.25', '26.0']]
CAE coordinates [['64.0', '-40.0'], ['64.0', '-37.0'], ['68.75', '-37.0'], ['68.75', '-30.0'], ['70.5', '-30.0'], ['70.5', '-26.75'], ['72.5', '-26.75'], ['75.0', '-26.75'], ['75.0', '-43.0'], ['72.5', '-43.0'], ['72.5', '-45.5'], ['67.5', '-45.5'], ['67.5', '-49.0'], ['64.0', '-49.0']]
CAM coordinates [['91.5', '56.0'], ['75.0', '56.0'], ['75.0', '52.5'], ['70.375', '52.5'], ['50.0', '52.5'], ['50.0', '55.0'], ['47.5', '55.0'], ['47.5', '57.0'], ['46.5', '57.0'], ['46.5', '68.0'], ['51.25', '68.0'], ['51.25', '77.0'], ['52.625', '77.0'], ['52.625', '80.0'], ['75.0', '80.0'], ['75.0', '85.0'], ['120.0', '85.0'], ['120.0', '86.5'], ['217.5', '86.5'], ['217.5', '80.0'], ['203.75', '80.0'], ['203.75', '77.0'], ['195.0', '77.0'], ['172.5', '77.0'], ['172.5', '80.0'], ['160.0', '80.0'], ['160.0', '82.0'], ['137.5', '82.0'], ['137.5', '73.5'], ['119.5', '73.5'], ['119.5', '60.0'], ['105.0', '60.0'], ['105.0', '62.0'], ['91.5', '62.0']]
CAP coordinates [['308.0', '-9.0'], ['308.0', '-15.0'], ['320.0', '-15.0'], ['320.0', '-9.0'], ['328.0', '-9.0'], ['328.0', '-24.5'], ['320.0', '-24.5'], ['320.0', '-28.0'], ['305.0', '-28.0'], ['300.0', '-28.0'], ['300.0', '-11.966666666666667'], ['300.0', '-9.0']]
CAR coordinates [['168.75', '-55.5'], ['168.75', '-64.0'], ['168.75', '-75.0'], ['135.5', '-75.0'], ['135.5', '-64.0'], ['102.5', '-64.0'], ['102.5', '-58.0'], ['97.5', '-58.0'], ['97.5', '-55.0'], ['92.5', '-55.0'], ['92.5', '-51.5'], ['90.0', '-51.5'], ['90.0', '-49.25'], ['120.0', '-49.25'], ['122.5', '-49.25'], ['122.5', '-53.0'], ['126.75', '-53.0'], ['126.75', '-53.5'], ['132.5', '-53.5'], ['132.5', '-55.5'], ['165.0', '-55.5']]
CAS coordinates [['343.0', '52.5'], ['343.0', '56.25'], ['343.0', '59.083333333333336'], ['347.5', '59.083333333333336'], ['347.5', '63.0'], ['353.75', '63.0'], ['353.75', '66.0'], ['5.0', '66.0'], ['5.0', '77.0'], ['51.25', '77.0'], ['51.25', '68.0'], ['46.5', '68.0'], ['46.5', '57.0'], ['36.5', '57.0'], ['36.5', '58.5'], ['28.625', '58.5'], ['28.625', '57.5'], ['25.5', '57.5'], ['25.5', '54.0'], ['20.5', '54.0'], ['20.5', '50.0'], ['16.75', '50.0'], ['16.75', '48.0'], ['13.0', '48.0'], ['13.0', '46.0'], ['2.5', '46.0'], ['2.5', '48.0'], ['353.75', '48.0'], ['353.75', '50.0'], ['350.0', '50.0'], ['350.0', '52.5']]
CEN coordinates [['165.0', '-35.0'], ['183.75', '-35.0'], ['183.75', '-33.0'], ['188.75', '-33.0'], ['188.75', '-28.5'], ['223.75', '-28.5'], ['223.75', '-42.0'], ['212.5', '-42.0'], ['212.5', '-55.0'], ['218.0', '-55.0'], ['218.0', '-64.0'], ['202.5', '-64.0'], ['192.5', '-64.0'], ['192.5', '-55.0'], ['177.5', '-55.0'], ['177.5', '-64.0'], ['168.75', '-64.0'], ['168.75', '-55.5'], ['165.0', '-55.5'], ['165.0', '-38.25']]
CEP coordinates [['300.0', '59.5'], ['300.0', '61.5'], ['306.25', '61.5'], ['306.25', '67.0'], ['310.0', '67.0'], ['310.0', '75.0'], ['302.5', '75.0'], ['302.5', '80.0'], ['315.0', '80.0'], ['315.0', '86.0'], ['315.0', '86.16666666666667'], ['345.0', '86.16666666666667'], ['345.0', '88.0'], ['120.0', '88.0'], ['120.0', '86.5'], ['120.0', '85.0'], ['75.0', '85.0'], ['75.0', '80.0'], ['52.625', '80.0'], ['52.625', '77.0'], ['51.25', '77.0'], ['5.0', '77.0'], ['5.0', '66.0'], ['353.75', '66.0'], ['353.75', '63.0'], ['347.5', '63.0'], ['347.5', '59.083333333333336'], ['343.0', '59.083333333333336'], ['343.0', '56.25'], ['334.75', '56.25'], ['334.75', '55.0'], ['332.0', '55.0'], ['332.0', '52.75'], ['329.5', '52.75'], ['329.5', '54.833333333333336'], ['309.0', '54.833333333333336'], ['309.0', '60.916666666666664'], ['308.05', '60.916666666666664'], ['308.05', '59.5']]
CET coordinates [['5.0', '0.0'], ['5.0', '2.0'], ['30.0', '2.0'], ['30.0', '9.916666666666666'], ['49.25', '9.916666666666666'], ['49.25', '0.0'], ['49.25', '-0.25'], ['39.75', '-0.25'], ['39.75', '-23.616666666666667'], ['25.0', '-23.616666666666667'], ['25.0', '-24.5'], ['357.5', '-24.5'], ['357.5', '-7.0'], ['5.0', '-7.0']]
CHA coordinates [['115.0', '-81.5'], ['115.0', '-75.0'], ['135.5', '-75.0'], ['168.75', '-75.0'], ['205.0', '-75.0'], ['205.0', '-81.5']]
CIR coordinates [['202.5', '-64.0'], ['218.0', '-64.0'], ['218.0', '-55.0'], ['225.75', '-55.0'], ['230.0', '-55.0'], ['230.0', '-60.0'], ['230.0', '-61.0'], ['227.5', '-61.0'], ['227.5', '-62.416666666666664'], ['223.75', '-62.416666666666664'], ['223.75', '-66.5'], ['221.25', '-66.5'], ['221.25', '-70.0'], ['205.0', '-70.0'], ['205.0', '-65.0'], ['202.5', '-65.0']]
CMA coordinates [['91.75', '-11.0'], ['110.5', '-11.0'], ['110.5', '-33.0'], ['98.75', '-33.0'], ['91.75', '-33.0'], ['91.75', '-26.75']]
CMI coordinates [['121.25', '0.0'], ['108.0', '0.0'], ['108.0', '1.5'], ['105.25', '1.5'], ['105.25', '5.5'], ['105.0', '5.5'], ['105.0', '10.0'], ['105.0', '12.5'], ['112.5', '12.5'], ['112.5', '13.5'], ['117.125', '13.5'], ['117.125', '10.0'], ['118.875', '10.0'], ['118.875', '7.0'], ['121.25', '7.0']]
CNC coordinates [['138.75', '7.0'], ['121.25', '7.0'], ['118.875', '7.0'], ['118.875', '10.0'], ['117.125', '10.0'], ['117.125', '13.5'], ['117.125', '20.0'], ['118.25', '20.0'], ['118.25', '28.0'], ['120.0', '28.0'], ['120.0', '33.5'], ['138.75', '33.5']]
COL coordinates [['75.0', '-43.0'], ['75.0', '-26.75'], ['91.75', '-26.75'], ['91.75', '-33.0'], ['98.75', '-33.0'], ['98.75', '-43.0'], ['90.0', '-43.0']]
COM coordinates [['178.0', '14.0'], ['178.0', '29.0'], ['180.0', '29.0'], ['180.0', '34.0'], ['185.0', '34.0'], ['185.0', '32.0'], ['198.75', '32.0'], ['198.75', '28.5'], ['202.5', '28.5'], ['202.5', '15.0'], ['192.5', '15.0'], ['192.5', '14.0']]
CRA coordinates [['267.5', '-37.0'], ['287.5', '-37.0'], ['287.5', '-44.5'], ['270.0', '-44.5'], ['267.5', '-44.5']]
CRB coordinates [['227.75', '26.0'], ['227.75', '33.0'], ['231.5', '33.0'], ['231.5', '40.0'], ['236.25', '40.0'], ['245.0', '40.0'], ['245.0', '27.0'], ['242.5', '27.0'], ['242.5', '26.0'], ['240.5', '26.0']]
CRT coordinates [['161.25', '-6.0'], ['172.75', '-6.0'], ['177.5', '-6.0'], ['177.5', '-11.0'], ['177.5', '-23.5'], ['162.5', '-23.5'], ['162.5', '-19.0'], ['161.25', '-19.0'], ['161.25', '-11.0']]
CRU coordinates [['177.5', '-55.0'], ['192.5', '-55.0'], ['192.5', '-64.0'], ['177.5', '-64.0']]
CRV coordinates [['192.5', '-11.0'], ['192.5', '-22.0'], ['188.75', '-22.0'], ['188.75', '-23.5'], ['177.5', '-23.5'], ['177.5', '-11.0']]
CVN coordinates [['180.0', '34.0'], ['180.0', '45.0'], ['181.25', '45.0'], ['181.25', '53.0'], ['202.5', '53.0'], ['202.5', '48.5'], ['210.5', '48.5'], ['210.5', '30.75'], ['209.375', '30.75'], ['209.375', '28.5'], ['202.5', '28.5'], ['198.75', '28.5'], ['198.75', '32.0'], ['185.0', '32.0'], ['185.0', '34.0']]
CYG coordinates [['288.875', '27.5'], ['288.875', '30.0'], ['290.375', '30.0'], ['290.375', '36.5'], ['291.0', '36.5'], ['291.0', '43.5'], ['287.5', '43.5'], ['287.5', '47.5'], ['286.25', '47.5'], ['286.25', '55.5'], ['291.25', '55.5'], ['291.25', '58.0'], ['296.5', '58.0'], ['296.5', '59.5'], ['300.0', '59.5'], ['308.05', '59.5'], ['308.05', '60.916666666666664'], ['309.0', '60.916666666666664'], ['309.0', '54.833333333333336'], ['329.5', '54.833333333333336'], ['329.5', '52.75'], ['329.5', '44.0'], ['328.625', '44.0'], ['328.625', '43.75'], ['328.125', '43.75'], ['328.125', '36.0'], ['326.0', '36.0'], ['326.0', '28.0'], ['321.25', '28.0'], ['313.75', '28.0'], ['313.75', '29.0'], ['295.0', '29.0'], ['295.0', '27.5']]
DEL coordinates [['308.0', '2.0'], ['304.5', '2.0'], ['304.5', '8.5'], ['302.125', '8.5'], ['302.125', '15.75'], ['303.75', '15.75'], ['303.75', '20.5'], ['308.5', '20.5'], ['308.5', '19.5'], ['315.75', '19.5'], ['315.75', '11.833333333333334'], ['313.125', '11.833333333333334'], ['313.125', '6.0'], ['312.5', '6.0'], ['312.5', '2.0']]
DOR coordinates [['57.5', '-52.833333333333336'], ['57.5', '-51.0'], ['61.25', '-51.0'], ['61.25', '-49.0'], ['64.0', '-49.0'], ['67.5', '-49.0'], ['67.5', '-54.0'], ['75.0', '-54.0'], ['75.0', '-56.5'], ['82.5', '-56.5'], ['82.5', '-61.0'], ['90.0', '-61.0'], ['90.0', '-64.0'], ['98.75', '-64.0'], ['98.75', '-70.0'], ['68.75', '-70.0'], ['68.75', '-66.5'], ['68.75', '-59.0'], ['65.0', '-59.0'], ['65.0', '-55.5'], ['60.0', '-55.5'], ['60.0', '-52.833333333333336']]
DRA coordinates [['137.5', '73.5'], ['137.5', '82.0'], ['160.0', '82.0'], ['160.0', '80.0'], ['172.5', '80.0'], ['172.5', '77.0'], ['195.0', '77.0'], ['195.0', '70.0'], ['210.0', '70.0'], ['210.0', '66.0'], ['235.0', '66.0'], ['235.0', '70.0'], ['248.0', '70.0'], ['248.0', '75.0'], ['262.5', '75.0'], ['262.5', '80.0'], ['270.0', '80.0'], ['270.0', '86.0'], ['315.0', '86.0'], ['315.0', '80.0'], ['302.5', '80.0'], ['302.5', '75.0'], ['310.0', '75.0'], ['310.0', '67.0'], ['306.25', '67.0'], ['306.25', '61.5'], ['300.0', '61.5'], ['300.0', '59.5'], ['296.5', '59.5'], ['296.5', '58.0'], ['291.25', '58.0'], ['291.25', '55.5'], ['286.25', '55.5'], ['286.25', '47.5'], ['273.5', '47.5'], ['273.5', '50.5'], ['255.0', '50.5'], ['255.0', '51.5'], ['236.25', '51.5'], ['236.25', '53.0'], ['228.75', '53.0'], ['228.75', '55.5'], ['216.25', '55.5'], ['216.25', '63.0'], ['202.5', '63.0'], ['202.5', '64.0'], ['180.0', '64.0'], ['180.0', '66.5'], ['170.0', '66.5'], ['170.0', '73.5']]
EQU coordinates [['312.5', '2.0'], ['312.5', '6.0'], ['313.125', '6.0'], ['313.125', '11.833333333333334'], ['315.75', '11.833333333333334'], ['316.75', '11.833333333333334'], ['316.75', '12.5'], ['320.0', '12.5'], ['320.0', '2.0']]
ERI coordinates [['53.75', '0.0'], ['69.25', '0.0'], ['70.0', '0.0'], ['70.0', '-4.0'], ['76.25', '-4.0'], ['76.25', '-11.0'], ['73.75', '-11.0'], ['73.75', '-13.5'], ['72.5', '-13.5'], ['72.5', '-26.75'], ['70.5', '-26.75'], ['70.5', '-30.0'], ['68.75', '-30.0'], ['68.75', '-37.0'], ['64.0', '-37.0'], ['64.0', '-40.0'], ['58.0', '-40.0'], ['58.0', '-44.0'], ['51.25', '-44.0'], ['51.25', '-46.0'], ['45.0', '-46.0'], ['45.0', '-49.0'], ['40.0', '-49.0'], ['40.0', '-51.0'], ['36.25', '-51.0'], ['36.25', '-54.0'], ['32.5', '-54.0'], ['32.5', '-57.5'], ['20.0', '-57.5'], ['20.0', '-52.5'], ['23.75', '-52.5'], ['23.75', '-50.5'], ['27.5', '-50.5'], ['27.5', '-47.833333333333336'], ['35.0', '-47.833333333333336'], ['35.0', '-40.0'], ['45.0', '-40.0'], ['45.0', '-38.416666666666664'], ['52.5', '-38.416666666666664'], ['52.5', '-36.0'], ['56.25', '-36.0'], ['56.25', '-23.616666666666667'], ['39.75', '-23.616666666666667'], ['39.75', '-0.25'], ['49.25', '-0.25'], ['53.75', '-0.25']]
FOR coordinates [['25.0', '-23.616666666666667'], ['39.75', '-23.616666666666667'], ['56.25', '-23.616666666666667'], ['56.25', '-36.0'], ['52.5', '-36.0'], ['52.5', '-38.416666666666664'], ['45.0', '-38.416666666666664'], ['45.0', '-40.0'], ['35.0', '-40.0'], ['25.0', '-40.0'], ['25.0', '-24.5']]
GEM coordinates [['94.625', '12.0'], ['94.625', '17.5'], ['93.25', '17.5'], ['93.25', '21.5'], ['88.25', '21.5'], ['88.25', '22.833333333333332'], ['88.25', '28.0'], ['98.0', '28.0'], ['98.0', '35.5'], ['110.5', '35.5'], ['116.25', '35.5'], ['116.25', '33.5'], ['120.0', '33.5'], ['120.0', '28.0'], ['118.25', '28.0'], ['118.25', '20.0'], ['117.125', '20.0'], ['117.125', '13.5'], ['112.5', '13.5'], ['112.5', '12.5'], ['105.0', '12.5'], ['105.0', '10.0'], ['104.0', '10.0'], ['104.0', '12.0']]
GRU coordinates [['320.0', '-37.0'], ['345.0', '-37.0'], ['350.0', '-37.0'], ['350.0', '-40.0'], ['350.0', '-57.0'], ['330.0', '-57.0'], ['330.0', '-50.0'], ['320.0', '-50.0'], ['320.0', '-44.5']]
HER coordinates [['244.0', '4.0'], ['241.25', '4.0'], ['241.25', '16.0'], ['238.75', '16.0'], ['238.75', '22.0'], ['240.5', '22.0'], ['240.5', '26.0'], ['242.5', '26.0'], ['242.5', '27.0'], ['245.0', '27.0'], ['245.0', '40.0'], ['236.25', '40.0'], ['236.25', '51.5'], ['255.0', '51.5'], ['255.0', '50.5'], ['273.5', '50.5'], ['273.5', '47.5'], ['272.625', '47.5'], ['272.625', '30.0'], ['275.5', '30.0'], ['275.5', '26.0'], ['283.0', '26.0'], ['283.0', '25.5'], ['283.0', '21.083333333333332'], ['283.0', '18.5'], ['283.0', '12.0'], ['279.93333333333334', '12.0'], ['273.75', '12.0'], ['273.75', '14.333333333333334'], ['258.75', '14.333333333333334'], ['258.75', '12.833333333333334'], ['251.25', '12.833333333333334'], ['251.25', '4.0']]
HOR coordinates [['64.0', '-40.0'], ['64.0', '-49.0'], ['61.25', '-49.0'], ['61.25', '-51.0'], ['57.5', '-51.0'], ['57.5', '-52.833333333333336'], ['52.5', '-52.833333333333336'], ['52.5', '-56.5'], ['48.0', '-56.5'], ['48.0', '-66.5'], ['32.5', '-66.5'], ['32.5', '-57.5'], ['32.5', '-54.0'], ['36.25', '-54.0'], ['36.25', '-51.0'], ['40.0', '-51.0'], ['40.0', '-49.0'], ['45.0', '-49.0'], ['45.0', '-46.0'], ['51.25', '-46.0'], ['51.25', '-44.0'], ['58.0', '-44.0'], ['58.0', '-40.0']]
HYA coordinates [['121.25', '0.0'], ['121.25', '7.0'], ['138.75', '7.0'], ['143.75', '7.0'], ['143.75', '0.0'], ['143.75', '-11.0'], ['161.25', '-11.0'], ['161.25', '-19.0'], ['162.5', '-19.0'], ['162.5', '-23.5'], ['177.5', '-23.5'], ['188.75', '-23.5'], ['188.75', '-22.0'], ['192.5', '-22.0'], ['213.75', '-22.0'], ['213.75', '-23.5'], ['223.75', '-23.5'], ['223.75', '-28.5'], ['188.75', '-28.5'], ['188.75', '-33.0'], ['183.75', '-33.0'], ['183.75', '-35.0'], ['165.0', '-35.0'], ['162.5', '-35.0'], ['162.5', '-30.833333333333332'], ['158.75', '-30.833333333333332'], ['158.75', '-28.833333333333332'], ['153.75', '-28.833333333333332'], ['153.75', '-25.5'], ['146.25', '-25.5'], ['146.25', '-24.0'], ['140.5', '-24.0'], ['136.25', '-24.0'], ['136.25', '-19.0'], ['128.75', '-19.0'], ['128.75', '-17.0'], ['125.5', '-17.0'], ['125.5', '-11.0'], ['121.25', '-11.0']]
HYI coordinates [['68.75', '-66.5'], ['68.75', '-70.0'], ['68.75', '-75.0'], ['52.5', '-75.0'], ['52.5', '-81.5'], ['0.0', '-81.5'], ['0.0', '-75.0'], ['11.25', '-75.0'], ['11.25', '-76.0'], ['20.0', '-76.0'], ['20.0', '-57.5'], ['32.5', '-57.5'], ['32.5', '-66.5'], ['48.0', '-66.5']]
IND coordinates [['320.0', '-75.0'], ['320.0', '-60.0'], ['305.0', '-60.0'], ['305.0', '-57.0'], ['305.0', '-44.5'], ['320.0', '-44.5'], ['320.0', '-50.0'], ['330.0', '-50.0'], ['330.0', '-57.0'], ['330.0', '-66.5'], ['350.0', '-66.5'], ['350.0', '-75.0']]
LAC coordinates [['328.125', '36.0'], ['328.125', '43.75'], ['328.625', '43.75'], ['328.625', '44.0'], ['329.5', '44.0'], ['329.5', '52.75'], ['332.0', '52.75'], ['332.0', '55.0'], ['334.75', '55.0'], ['334.75', '56.25'], ['343.0', '56.25'], ['343.0', '52.5'], ['343.0', '34.5'], ['342.25', '34.5'], ['342.25', '35.0'], ['330.0', '35.0'], ['330.0', '36.0']]
LEO coordinates [['161.25', '0.0'], ['161.25', '7.0'], ['143.75', '7.0'], ['138.75', '7.0'], ['138.75', '33.5'], ['148.25', '33.5'], ['148.25', '28.5'], ['157.5', '28.5'], ['157.5', '23.5'], ['161.25', '23.5'], ['161.25', '25.5'], ['165.0', '25.5'], ['165.0', '29.0'], ['178.0', '29.0'], ['178.0', '14.0'], ['178.0', '11.0'], ['172.75', '11.0'], ['172.75', '0.0'], ['172.75', '-6.0'], ['161.25', '-6.0']]
LEP coordinates [['72.5', '-26.75'], ['72.5', '-13.5'], ['73.75', '-13.5'], ['73.75', '-11.0'], ['76.25', '-11.0'], ['87.5', '-11.0'], ['91.75', '-11.0'], ['91.75', '-26.75'], ['75.0', '-26.75']]
LIB coordinates [['226.25', '0.0'], ['226.25', '-2.75'], ['238.75', '-2.75'], ['238.75', '-8.0'], ['238.75', '-20.0'], ['235.0', '-20.0'], ['235.0', '-28.5'], ['223.75', '-28.5'], ['223.75', '-23.5'], ['213.75', '-23.5'], ['213.75', '-22.0'], ['213.75', '-8.0'], ['220.0', '-8.0'], ['220.0', '0.0']]
LMI coordinates [['138.75', '33.5'], ['138.75', '39.75'], ['143.75', '39.75'], ['143.75', '42.0'], ['152.5', '42.0'], ['152.5', '40.0'], ['161.75', '40.0'], ['161.75', '34.0'], ['165.0', '34.0'], ['165.0', '29.0'], ['165.0', '25.5'], ['161.25', '25.5'], ['161.25', '23.5'], ['157.5', '23.5'], ['157.5', '28.5'], ['148.25', '28.5'], ['148.25', '33.5']]
LUP coordinates [['212.5', '-55.0'], ['212.5', '-42.0'], ['223.75', '-42.0'], ['223.75', '-28.5'], ['235.0', '-28.5'], ['240.0', '-28.5'], ['240.0', '-42.0'], ['235.0', '-42.0'], ['235.0', '-48.0'], ['230.0', '-48.0'], ['230.0', '-54.0'], ['225.75', '-54.0'], ['225.75', '-55.0'], ['218.0', '-55.0']]
LYN coordinates [['110.5', '35.5'], ['110.5', '44.5'], ['102.0', '44.5'], ['102.0', '50.0'], ['97.5', '50.0'], ['97.5', '54.0'], ['91.5', '54.0'], ['91.5', '56.0'], ['91.5', '62.0'], ['105.0', '62.0'], ['105.0', '60.0'], ['119.5', '60.0'], ['126.25', '60.0'], ['126.25', '47.0'], ['137.5', '47.0'], ['137.5', '42.0'], ['143.75', '42.0'], ['143.75', '39.75'], ['138.75', '39.75'], ['138.75', '33.5'], ['120.0', '33.5'], ['116.25', '33.5'], ['116.25', '35.5']]
LYR coordinates [['283.0', '25.5'], ['283.0', '26.0'], ['275.5', '26.0'], ['275.5', '30.0'], ['272.625', '30.0'], ['272.625', '47.5'], ['273.5', '47.5'], ['286.25', '47.5'], ['287.5', '47.5'], ['287.5', '43.5'], ['291.0', '43.5'], ['291.0', '36.5'], ['290.375', '36.5'], ['290.375', '30.0'], ['288.875', '30.0'], ['288.875', '27.5'], ['288.875', '25.5']]
MEN coordinates [['115.0', '-85.0'], ['52.5', '-85.0'], ['52.5', '-81.5'], ['52.5', '-75.0'], ['68.75', '-75.0'], ['68.75', '-70.0'], ['98.75', '-70.0'], ['98.75', '-75.0'], ['115.0', '-75.0'], ['115.0', '-81.5']]
MIC coordinates [['305.0', '-28.0'], ['320.0', '-28.0'], ['320.0', '-37.0'], ['320.0', '-44.5'], ['305.0', '-44.5']]
MON coordinates [['93.625', '0.0'], ['93.625', '10.0'], ['94.625', '10.0'], ['94.625', '12.0'], ['104.0', '12.0'], ['104.0', '10.0'], ['105.0', '10.0'], ['105.0', '5.5'], ['105.25', '5.5'], ['105.25', '1.5'], ['108.0', '1.5'], ['108.0', '0.0'], ['121.25', '0.0'], ['121.25', '-11.0'], ['110.5', '-11.0'], ['91.75', '-11.0'], ['87.5', '-11.0'], ['87.5', '-4.0'], ['93.625', '-4.0']]
MUS coordinates [['168.75', '-64.0'], ['177.5', '-64.0'], ['192.5', '-64.0'], ['202.5', '-64.0'], ['202.5', '-65.0'], ['205.0', '-65.0'], ['205.0', '-70.0'], ['205.0', '-75.0'], ['168.75', '-75.0']]
NOR coordinates [['230.0', '-60.0'], ['230.0', '-55.0'], ['225.75', '-55.0'], ['225.75', '-54.0'], ['230.0', '-54.0'], ['230.0', '-48.0'], ['235.0', '-48.0'], ['235.0', '-42.0'], ['240.0', '-42.0'], ['246.3125', '-42.0'], ['246.3125', '-44.5'], ['246.3125', '-60.0']]
OCT coordinates [['0.0', '-75.0'], ['0.0', '-81.5'], ['52.5', '-81.5'], ['52.5', '-85.0'], ['115.0', '-85.0'], ['115.0', '-81.5'], ['205.0', '-81.5'], ['270.0', '-81.5'], ['270.0', '-75.0'], ['320.0', '-75.0'], ['350.0', '-75.0']]
OPH coordinates [['244.0', '0.0'], ['244.0', '4.0'], ['251.25', '4.0'], ['251.25', '12.833333333333334'], ['258.75', '12.833333333333334'], ['258.75', '14.333333333333334'], ['273.75', '14.333333333333334'], ['273.75', '12.0'], ['279.93333333333334', '12.0'], ['279.93333333333334', '6.25'], ['273.75', '6.25'], ['273.75', '4.5'], ['276.375', '4.5'], ['276.375', '3.0'], ['273.75', '3.0'], ['273.75', '0.0'], ['267.5', '0.0'], ['267.5', '-4.0'], ['269.5', '-4.0'], ['269.5', '-10.0'], ['265.0', '-10.0'], ['265.0', '-10.333333333333334'], ['263.75', '-10.333333333333334'], ['263.75', '-10.0'], ['257.5', '-10.0'], ['257.5', '-16.0'], ['264.0', '-16.0'], ['264.0', '-30.0'], ['251.25', '-30.0'], ['251.25', '-23.416666666666668'], ['244.0', '-23.416666666666668'], ['244.0', '-18.75'], ['245.625', '-18.75'], ['245.625', '-17.75'], ['244.0', '-17.75'], ['244.0', '-8.0'], ['238.75', '-8.0'], ['238.75', '-2.75'], ['244.0', '-2.75']]
ORI coordinates [['69.25', '0.0'], ['69.25', '15.5'], ['74.5', '15.5'], ['74.5', '16.0'], ['80.0', '16.0'], ['80.0', '15.5'], ['84.0', '15.5'], ['84.0', '12.5'], ['86.5', '12.5'], ['86.5', '18.0'], ['85.5', '18.0'], ['85.5', '22.833333333333332'], ['88.25', '22.833333333333332'], ['88.25', '21.5'], ['93.25', '21.5'], ['93.25', '17.5'], ['94.625', '17.5'], ['94.625', '12.0'], ['94.625', '10.0'], ['93.625', '10.0'], ['93.625', '0.0'], ['93.625', '-4.0'], ['87.5', '-4.0'], ['87.5', '-11.0'], ['76.25', '-11.0'], ['76.25', '-4.0'], ['70.0', '-4.0'], ['70.0', '0.0']]
PAV coordinates [['270.0', '-75.0'], ['270.0', '-66.5'], ['262.5', '-66.5'], ['262.5', '-57.0'], ['270.0', '-57.0'], ['305.0', '-57.0'], ['305.0', '-60.0'], ['320.0', '-60.0'], ['320.0', '-75.0']]
PEG coordinates [['320.0', '2.0'], ['320.0', '12.5'], ['316.75', '12.5'], ['316.75', '11.833333333333334'], ['315.75', '11.833333333333334'], ['315.75', '19.5'], ['318.75', '19.5'], ['318.75', '23.5'], ['321.25', '23.5'], ['321.25', '28.0'], ['326.0', '28.0'], ['326.0', '36.0'], ['328.125', '36.0'], ['330.0', '36.0'], ['330.0', '35.0'], ['342.25', '35.0'], ['342.25', '34.5'], ['343.0', '34.5'], ['352.5', '34.5'], ['352.5', '32.083333333333336'], ['356.25', '32.083333333333336'], ['356.25', '31.333333333333332'], ['0.0', '31.333333333333332'], ['0.0', '28.0'], ['1.0', '28.0'], ['1.0', '22.0'], ['2.125', '22.0'], ['2.125', '21.0'], ['2.125', '12.5'], ['0.0', '12.5'], ['0.0', '10.0'], ['357.5', '10.0'], ['357.5', '7.5'], ['341.25', '7.5'], ['341.25', '2.0'], ['330.0', '2.0'], ['330.0', '1.75'], ['325.0', '1.75'], ['325.0', '2.75'], ['322.0', '2.75'], ['322.0', '2.0']]
PER coordinates [['40.75', '30.666666666666668'], ['40.75', '34.0'], ['38.5', '34.0'], ['38.5', '36.75'], ['37.75', '36.75'], ['37.75', '50.5'], ['30.625', '50.5'], ['30.625', '47.0'], ['25.0', '47.0'], ['25.0', '50.0'], ['20.5', '50.0'], ['20.5', '54.0'], ['25.5', '54.0'], ['25.5', '57.5'], ['28.625', '57.5'], ['28.625', '58.5'], ['36.5', '58.5'], ['36.5', '57.0'], ['46.5', '57.0'], ['47.5', '57.0'], ['47.5', '55.0'], ['50.0', '55.0'], ['50.0', '52.5'], ['70.375', '52.5'], ['70.375', '36.0'], ['67.5', '36.0'], ['67.5', '30.666666666666668'], ['50.5', '30.666666666666668']]
PHE coordinates [['350.0', '-40.0'], ['25.0', '-40.0'], ['35.0', '-40.0'], ['35.0', '-47.833333333333336'], ['27.5', '-47.833333333333336'], ['27.5', '-50.5'], ['23.75', '-50.5'], ['23.75', '-52.5'], ['20.0', '-52.5'], ['20.0', '-57.5'], ['350.0', '-57.5'], ['350.0', '-57.0']]
PIC coordinates [['90.0', '-43.0'], ['90.0', '-49.25'], ['90.0', '-51.5'], ['92.5', '-51.5'], ['92.5', '-55.0'], ['97.5', '-55.0'], ['97.5', '-58.0'], ['102.5', '-58.0'], ['102.5', '-64.0'], ['98.75', '-64.0'], ['90.0', '-64.0'], ['90.0', '-61.0'], ['82.5', '-61.0'], ['82.5', '-56.5'], ['75.0', '-56.5'], ['75.0', '-54.0'], ['67.5', '-54.0'], ['67.5', '-49.0'], ['67.5', '-45.5'], ['72.5', '-45.5'], ['72.5', '-43.0'], ['75.0', '-43.0']]
PSA coordinates [['345.0', '-24.5'], ['345.0', '-37.0'], ['320.0', '-37.0'], ['320.0', '-28.0'], ['320.0', '-24.5'], ['328.0', '-24.5']]
PSC coordinates [['341.25', '0.0'], ['341.25', '2.0'], ['341.25', '7.5'], ['357.5', '7.5'], ['357.5', '10.0'], ['0.0', '10.0'], ['0.0', '12.5'], ['2.125', '12.5'], ['2.125', '21.0'], ['12.75', '21.0'], ['12.75', '23.75'], ['10.75', '23.75'], ['10.75', '33.0'], ['21.125', '33.0'], ['21.125', '28.0'], ['25.0', '28.0'], ['25.0', '25.0'], ['25.0', '9.916666666666666'], ['30.0', '9.916666666666666'], ['30.0', '2.0'], ['5.0', '2.0'], ['5.0', '0.0'], ['5.0', '-7.0'], ['357.5', '-7.0'], ['357.5', '-4.0'], ['341.25', '-4.0']]
PUP coordinates [['110.5', '-11.0'], ['121.25', '-11.0'], ['125.5', '-11.0'], ['125.5', '-17.0'], ['125.5', '-35.25'], ['125.5', '-43.0'], ['120.0', '-43.0'], ['120.0', '-49.25'], ['90.0', '-49.25'], ['90.0', '-43.0'], ['98.75', '-43.0'], ['98.75', '-33.0'], ['110.5', '-33.0']]
PYX coordinates [['125.5', '-17.0'], ['128.75', '-17.0'], ['128.75', '-19.0'], ['136.25', '-19.0'], ['136.25', '-24.0'], ['140.5', '-24.0'], ['140.5', '-35.25'], ['125.5', '-35.25']]
RET coordinates [['48.0', '-66.5'], ['48.0', '-56.5'], ['52.5', '-56.5'], ['52.5', '-52.833333333333336'], ['57.5', '-52.833333333333336'], ['60.0', '-52.833333333333336'], ['60.0', '-55.5'], ['65.0', '-55.5'], ['65.0', '-59.0'], ['68.75', '-59.0'], ['68.75', '-66.5']]
SCL coordinates [['345.0', '-24.5'], ['357.5', '-24.5'], ['25.0', '-24.5'], ['25.0', '-40.0'], ['350.0', '-40.0'], ['350.0', '-37.0'], ['345.0', '-37.0']]
SCO coordinates [['238.75', '-8.0'], ['244.0', '-8.0'], ['244.0', '-17.75'], ['245.625', '-17.75'], ['245.625', '-18.75'], ['244.0', '-18.75'], ['244.0', '-23.416666666666668'], ['251.25', '-23.416666666666668'], ['251.25', '-30.0'], ['264.0', '-30.0'], ['267.5', '-30.0'], ['267.5', '-37.0'], ['267.5', '-44.5'], ['246.3125', '-44.5'], ['246.3125', '-42.0'], ['240.0', '-42.0'], ['240.0', '-28.5'], ['235.0', '-28.5'], ['235.0', '-20.0'], ['238.75', '-20.0']]
SCT coordinates [['273.75', '-16.0'], ['273.75', '-4.0'], ['278.75', '-4.0'], ['283.0', '-4.0'], ['283.0', '-11.966666666666667'], ['283.0', '-16.0']]
SER1 coordinates [['226.25', '0.0'], ['226.25', '8.0'], ['226.25', '26.0'], ['227.75', '26.0'], ['240.5', '26.0'], ['240.5', '22.0'], ['238.75', '22.0'], ['238.75', '16.0'], ['241.25', '16.0'], ['241.25', '4.0'], ['244.0', '4.0'], ['244.0', '0.0'], ['244.0', '-2.75'], ['238.75', '-2.75'], ['226.25', '-2.75']]
SER2 coordinates [['273.75', '0.0'], ['273.75', '3.0'], ['276.375', '3.0'], ['276.375', '4.5'], ['273.75', '4.5'], ['273.75', '6.25'], ['279.93333333333334', '6.25'], ['283.0', '6.25'], ['283.0', '2.0'], ['278.75', '2.0'], ['278.75', '0.0'], ['278.75', '-4.0'], ['273.75', '-4.0'], ['273.75', '-16.0'], ['264.0', '-16.0'], ['257.5', '-16.0'], ['257.5', '-10.0'], ['263.75', '-10.0'], ['263.75', '-10.333333333333334'], ['265.0', '-10.333333333333334'], ['265.0', '-10.0'], ['269.5', '-10.0'], ['269.5', '-4.0'], ['267.5', '-4.0'], ['267.5', '0.0']]
SEX coordinates [['143.75', '0.0'], ['143.75', '7.0'], ['161.25', '7.0'], ['161.25', '0.0'], ['161.25', '-6.0'], ['161.25', '-11.0'], ['143.75', '-11.0']]
SGE coordinates [['283.0', '18.5'], ['283.0', '21.083333333333332'], ['288.75', '21.083333333333332'], ['288.75', '19.166666666666668'], ['297.5', '19.166666666666668'], ['297.5', '21.25'], ['303.75', '21.25'], ['303.75', '20.5'], ['303.75', '15.75'], ['302.125', '15.75'], ['297.5', '15.75'], ['297.5', '16.166666666666668'], ['285.0', '16.166666666666668'], ['285.0', '18.5']]
SGR coordinates [['283.0', '-11.966666666666667'], ['300.0', '-11.966666666666667'], ['300.0', '-28.0'], ['305.0', '-28.0'], ['305.0', '-44.5'], ['287.5', '-44.5'], ['287.5', '-37.0'], ['267.5', '-37.0'], ['267.5', '-30.0'], ['264.0', '-30.0'], ['264.0', '-16.0'], ['273.75', '-16.0'], ['283.0', '-16.0']]
TAU coordinates [['49.25', '-0.25'], ['49.25', '0.0'], ['49.25', '9.916666666666666'], ['49.25', '19.0'], ['50.5', '19.0'], ['50.5', '30.666666666666668'], ['67.5', '30.666666666666668'], ['67.5', '30.0'], ['71.25', '30.0'], ['71.25', '28.5'], ['88.25', '28.5'], ['88.25', '28.0'], ['88.25', '22.833333333333332'], ['85.5', '22.833333333333332'], ['85.5', '18.0'], ['86.5', '18.0'], ['86.5', '12.5'], ['84.0', '12.5'], ['84.0', '15.5'], ['80.0', '15.5'], ['80.0', '16.0'], ['74.5', '16.0'], ['74.5', '15.5'], ['69.25', '15.5'], ['69.25', '0.0'], ['53.75', '0.0'], ['53.75', '-0.25']]
TEL coordinates [['305.0', '-57.0'], ['270.0', '-57.0'], ['270.0', '-44.5'], ['287.5', '-44.5'], ['305.0', '-44.5']]
TRA coordinates [['221.25', '-70.0'], ['221.25', '-66.5'], ['223.75', '-66.5'], ['223.75', '-62.416666666666664'], ['227.5', '-62.416666666666664'], ['227.5', '-61.0'], ['230.0', '-61.0'], ['230.0', '-60.0'], ['246.3125', '-60.0'], ['246.3125', '-61.0'], ['248.75', '-61.0'], ['248.75', '-62.416666666666664'], ['251.25', '-62.416666666666664'], ['251.25', '-65.0'], ['252.5', '-65.0'], ['252.5', '-66.5'], ['255.0', '-66.5'], ['255.0', '-70.0']]
TRI coordinates [['25.0', '25.0'], ['25.0', '28.0'], ['21.125', '28.0'], ['21.125', '33.0'], ['21.125', '35.0'], ['30.0', '35.0'], ['30.0', '36.75'], ['37.75', '36.75'], ['38.5', '36.75'], ['38.5', '34.0'], ['40.75', '34.0'], ['40.75', '30.666666666666668'], ['36.25', '30.666666666666668'], ['36.25', '27.25'], ['28.75', '27.25'], ['28.75', '25.0']]
TUC coordinates [['350.0', '-75.0'], ['350.0', '-66.5'], ['330.0', '-66.5'], ['330.0', '-57.0'], ['350.0', '-57.0'], ['350.0', '-57.5'], ['20.0', '-57.5'], ['20.0', '-76.0'], ['11.25', '-76.0'], ['11.25', '-75.0'], ['0.0', '-75.0']]
UMA coordinates [['143.75', '42.0'], ['137.5', '42.0'], ['137.5', '47.0'], ['126.25', '47.0'], ['126.25', '60.0'], ['119.5', '60.0'], ['119.5', '73.5'], ['137.5', '73.5'], ['170.0', '73.5'], ['170.0', '66.5'], ['180.0', '66.5'], ['180.0', '64.0'], ['202.5', '64.0'], ['202.5', '63.0'], ['216.25', '63.0'], ['216.25', '55.5'], ['210.5', '55.5'], ['210.5', '48.5'], ['202.5', '48.5'], ['202.5', '53.0'], ['181.25', '53.0'], ['181.25', '45.0'], ['180.0', '45.0'], ['180.0', '34.0'], ['180.0', '29.0'], ['178.0', '29.0'], ['165.0', '29.0'], ['165.0', '34.0'], ['161.75', '34.0'], ['161.75', '40.0'], ['152.5', '40.0'], ['152.5', '42.0']]
UMI coordinates [['195.0', '77.0'], ['203.75', '77.0'], ['203.75', '80.0'], ['217.5', '80.0'], ['217.5', '86.5'], ['120.0', '86.5'], ['120.0', '88.0'], ['345.0', '88.0'], ['345.0', '86.16666666666667'], ['315.0', '86.16666666666667'], ['315.0', '86.0'], ['270.0', '86.0'], ['270.0', '80.0'], ['262.5', '80.0'], ['262.5', '75.0'], ['248.0', '75.0'], ['248.0', '70.0'], ['235.0', '70.0'], ['235.0', '66.0'], ['210.0', '66.0'], ['210.0', '70.0'], ['195.0', '70.0']]
VEL coordinates [['165.0', '-55.5'], ['132.5', '-55.5'], ['132.5', '-53.5'], ['126.75', '-53.5'], ['126.75', '-53.0'], ['122.5', '-53.0'], ['122.5', '-49.25'], ['120.0', '-49.25'], ['120.0', '-43.0'], ['125.5', '-43.0'], ['125.5', '-35.25'], ['140.5', '-35.25'], ['140.5', '-38.25'], ['165.0', '-38.25']]
VIR coordinates [['172.75', '0.0'], ['172.75', '11.0'], ['178.0', '11.0'], ['178.0', '14.0'], ['192.5', '14.0'], ['192.5', '15.0'], ['202.5', '15.0'], ['202.5', '8.0'], ['226.25', '8.0'], ['226.25', '0.0'], ['220.0', '0.0'], ['220.0', '-8.0'], ['213.75', '-8.0'], ['213.75', '-22.0'], ['192.5', '-22.0'], ['192.5', '-11.0'], ['177.5', '-11.0'], ['177.5', '-6.0'], ['172.75', '-6.0']]
VOL coordinates [['98.75', '-64.0'], ['102.5', '-64.0'], ['135.5', '-64.0'], ['135.5', '-75.0'], ['115.0', '-75.0'], ['98.75', '-75.0'], ['98.75', '-70.0']]
VUL coordinates [['283.0', '21.083333333333332'], ['283.0', '25.5'], ['288.875', '25.5'], ['288.875', '27.5'], ['295.0', '27.5'], ['295.0', '29.0'], ['313.75', '29.0'], ['313.75', '28.0'], ['321.25', '28.0'], ['321.25', '23.5'], ['318.75', '23.5'], ['318.75', '19.5'], ['315.75', '19.5'], ['308.5', '19.5'], ['308.5', '20.5'], ['303.75', '20.5'], ['303.75', '21.25'], ['297.5', '21.25'], ['297.5', '19.166666666666668'], ['288.75', '19.166666666666668'], ['288.75', '21.083333333333332']]

245
plugins/simu.py Executable file
View File

@ -0,0 +1,245 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
LJ v0.8.0
Pygame Simulator plugin for LJ
LICENCE : CC
Sam Neurohack, loloster,
OSC server with :
/simu/quit
/simu/newpl new pl number to draw
/simu/newclient new client number to draw
'''
#from __future__ import print_function
import time
import math
import random
import itertools
import sys
import os
#import thread
import redis
import pygame
import pdb
import types, ast, argparse
from OSC import OSCServer, OSCClient, OSCMessage
pl = [[],[],[],[]]
print ("")
print ("LJ v0.8.0 : Pygame simulator")
print ("")
print ("Arguments parsing if needed...")
#
# Arguments parsing
#
argsparser = argparse.ArgumentParser(description="Available commands")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int)
argsparser.add_argument("-v","--verbose",help="Verbosity level (0 by default)",type=int)
args = argsparser.parse_args()
if args.client:
ljclient = args.client
else:
ljclient = 0
# Laser choice
if args.laser:
simuPL = args.laser
else:
simuPL = 0
# Debug ?
if args.verbose:
debug = args.verbose
else:
debug = 0
# Redis Computer IP
if args.redisIP != None:
redisIP = args.redisIP
else:
redisIP = '127.0.0.1'
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
#
# OSC
#
oscIPin = "127.0.0.1"
oscPORTin = 8008
ljIP = "127.0.0.1"
ljPort = 8002
print ("")
print ("Receiving on ", oscIPin, ":",str(oscPORTin))
oscserver = OSCServer( (oscIPin, oscPORTin) )
oscserver.timeout = 0
OSCRunning = True
def handle_timeout(self):
self.timed_out = True
oscserver.handle_timeout = types.MethodType(handle_timeout, oscserver)
def sendLJ(address, args):
if debug >0:
print "Sending to LJ...", address, args
osclientlj = OSCClient()
osclientlj.connect((ljIP, ljPort))
oscmsg = OSCMessage()
oscmsg.setAddress(address)
oscmsg.append(args)
try:
osclientlj.sendto(oscmsg, (ljIP, ljPort))
oscmsg.clearData()
return True
except:
print 'Connection to LJ IP', ljIP,'port', ljPort, 'refused : died ?'
return False
# RAW OSC Frame available ?
def osc_frame():
# clear timed_out flag
oscserver.timed_out = False
# handle all pending requests then return
while not oscserver.timed_out:
oscserver.handle_request()
# /quit
def quit(path, tags, args, source):
pygame.quit()
print "pySimu Stopped by /quit."
sys.exit()
# /start : 0 exit
def start(path, tags, args, source):
print args, type(args)
if args[0] == 0:
pygame.quit()
print "pySimu stopped by /start 0"
sys.exit()
# Answer to LJ pings
def ping(path, tags, args, source):
# Will receive message address, and message data flattened in s, x, y
print "Simu got /ping with value", args[0]
print "Simu replied with /pong simu"
sendLJ("/pong","simu")
# /newPL pointlistnumber
def newPL(path, tags, args, source):
user = ''.join(path.split("/"))
print ""
print user,path,args
print "Simulator got a new point list number :", args[0]
simuPL = args[0]
# /newClient clientnumber
def newClient(path, tags, args, source):
user = ''.join(path.split("/"))
print ""
print user,path,args
print "Simulator got a new client number : ", args[0]
ljclient = args[0]
oscserver.addMsgHandler( "/quit", quit )
oscserver.addMsgHandler( "/ping", ping )
oscserver.addMsgHandler( "/pysimu/start", start )
oscserver.addMsgHandler( "/pysimu/newpl", newPL )
oscserver.addMsgHandler( "/pysimu/newclient", newClient )
#
# Pygame screen
#
def RenderScreen(surface):
if len(pl[simuPL]):
xyc_prev = pl[simuPL][0]
#pygame.draw.line(surface,self.black_hole_color,(x_bh_cur, y_bh_cur), (x_bh_next, y_bh_next))
#pygame.draw.line(surface,self.spoke_color,(x_bh_cur, y_bh_cur), (x_area_cur, y_area_cur))
for xyc in pl[simuPL]:
c = int(xyc[2])
if c: pygame.draw.line(surface,c,xyc_prev[:2],xyc[:2],3)
xyc_prev = xyc
screen_size = [700,700]
pygame.init()
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("LJ Simulator")
clock = pygame.time.Clock()
update_screen = False
print ("Simulator displays client", ljclient, "point list", str(simuPL))
#
# Main
#
try:
while True:
# pending osc message ?
osc_frame()
# Pygame events
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
screen.fill(0)
pl[simuPL] = ast.literal_eval(r.get("/pl/"+ str(ljclient) + "/" + str(simuPL)))
if update_screen:
update_screen = False
RenderScreen(screen)
pygame.display.flip()
else:
update_screen = True
clock.tick(30)
# time.sleep(0.001)
except KeyboardInterrupt:
pass
finally:
pygame.quit()
print "pySimu Stopped."

130
plugins/textcycl.py Normal file
View File

@ -0,0 +1,130 @@
# coding=UTF-8
'''
Cycling text on one LJ laser.
LICENCE : CC
'''
import redis
import lj3
import sys,time
import argparse
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
#from osc4py3 import oscmethod as osm
from osc4py3.oscmethod import *
OSCinPort = 8007
duration = 300
lasertext = ["TEAMLASER","FANFAN","LOLOSTER","SAM"]
'''
is_py2 = sys.version[0] == '2'
if is_py2:
from Queue import Queue
else:
from queue import Queue
'''
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Text Cycling for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
argsparser.add_argument("-l","--laser",help="Laser number to be displayed (0 by default)",type=int)
argsparser.add_argument("-v","--verbose",help="Verbosity level (0 by default)",type=int)
args = argsparser.parse_args()
if args.client:
ljclient = args.client
else:
ljclient = 0
if args.laser:
plnumber = args.laser
else:
plnumber = 0
if args.verbose:
debug = args.verbose
else:
debug = 0
# Redis Computer IP
if args.redisIP != None:
redisIP = args.redisIP
else:
redisIP = '127.0.0.1'
lj3.Config(redisIP,ljclient)
#r = redis.StrictRedis(host=redisIP, port=6379, db=0)
# If you want to use rgb for color :
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
def WebStatus(message):
lj3.Send("/status",message)
def OSCljclient(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /cycl/ljclient with value", value)
ljclient = value
lj3.LjClient(ljclient)
osc_startup()
osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/ping*", lj3.OSCping)
osc_method("/cycl/ljclient", OSCljclient)
WebStatus("Textcycl")
def Run():
counter =0
step = 0
timing = -1
color = rgb2int(255,255,255)
try:
while 1:
if timing == duration or timing == -1:
message = lasertext[step]
lj3.Text(message, color, PL = 0, xpos = 300, ypos = 300, resize = 1, rotx =0, roty =0 , rotz=0)
lj3.DrawPL(0)
timing = 0
else:
step += 1
if step >3:
step =0
timing += 1
time.sleep(0.01)
except KeyboardInterrupt:
pass
# Gently stop on CTRL C
finally:
WebStatus("Textcycl stop")
print("Stopping OSC...")
lj3.OSCstop()
print ("Textcycl Stopped.")
Run()

View File

@ -24,6 +24,7 @@ def Write():
config.set('General', 'nozoscip', str(gstt.nozoscIP))
config.set('General', 'debug', str(gstt.debug))
for i in range(gstt.LaserNumber):
laser = 'laser' + str(i)
config.set(laser, 'ip', str(gstt.lasersIPS[i]))
@ -49,7 +50,10 @@ def Read():
gstt.oscIPin = config.get('General', 'bhoroscip')
gstt.nozoscip = config.get('General', 'nozoscip')
gstt.debug = config.get('General', 'debug')
gstt.plugins = ast.literal_eval(config.get('plugins', 'plugins'))
print ""
for i in range(4):
laser = 'laser' + str(i)
gstt.lasersIPS[i]= config.get(laser, 'ip')

Binary file not shown.

View File

@ -8,17 +8,13 @@
function noMenu() {
// Set all central menu buttons with normal button style
var x = document.getElementById("align");
var x = document.getElementById("align");
x.value = 0 ;
var x = document.getElementById("run");
x.value = 0 ;
var x = document.getElementById("simu");
x.value = 0 ;
var x = document.getElementById("live");
x.value = 0 ;
var x = document.getElementById("nozoid");
x.value = 0 ;
var x = document.getElementById("planet");
x.value = 0 ;
// Hide all possible main central grids.
@ -26,16 +22,11 @@
x.style.display = "none";
var x = document.getElementById("mgsimu");
x.style.display = "none";
var x = document.getElementById("cnvbuttons");
x.style.display = "none";
var x = document.getElementById("mgrun");
x.style.display = "none";
var x = document.getElementById("mglive");
x.style.display = "none";
var x = document.getElementById("mgnozoid");
x.style.display = "none";
var x = document.getElementById("mgplanet");
x.style.display = "none";
}
function showAlign() {
@ -58,7 +49,7 @@
noMenu();
var x = document.getElementById("mgsimu");
x.style.display = "grid";
var x = document.getElementById("cnvbuttons");
var x = document.getElementById("cnvbuttons");
x.style.display = "grid";
var x = document.getElementById("simu");
x.value = 1 ;
@ -72,24 +63,71 @@
x.value = 1 ;
}
function showNozoid() {
noMenu();
var x = document.getElementById("mgnozoid");
x.style.display = "grid";
var x = document.getElementById("nozoid");
x.value = 1 ;
}
function showPlanet() {
noMenu();
var x = document.getElementById("mgplanet");
//
// SimuUIs
//
function nosimuUI() {
// Hide all possible main central grids.
var x = document.getElementById("planetUI");
x.style.display = "none";
var x = document.getElementById("nozoidUI");
x.style.display = "none";
var x = document.getElementById("aiUI");
x.style.display = "none";
var x = document.getElementById("lissaUI");
x.style.display = "none";
var x = document.getElementById("vjUI");
x.style.display = "none";
var x = document.getElementById("wordsUI");
x.style.display = "none";
}
function showplanetUI() {
nosimuUI();
var x = document.getElementById("planetUI");
x.style.display = "grid";
var x = document.getElementById("cnvbuttons");
x.style.display = "grid";
var x = document.getElementById("planet");
x.value = 1 ;
_WS.send("/planet/ping");
}
function shownozoidUI() {
nosimuUI();
var x = document.getElementById("nozoidUI");
x.style.display = "grid";
_WS.send("/nozoid/ping");
}
function showaiUI() {
nosimuUI();
var x = document.getElementById("aiUI");
x.style.display = "grid";
}
function showlissaUI() {
nosimuUI();
var x = document.getElementById("lissaUI");
x.style.display = "grid";
}
function showvjUI() {
nosimuUI();
var x = document.getElementById("vjUI");
x.style.display = "grid";
_WS.send("/bank0/ping");
}
function showwordsUI() {
nosimuUI();
var x = document.getElementById("wordsUI");
x.style.display = "grid";
_WS.send("/words/ping");
}
//
// Button clicked
//
function buttonClicked(clicked_id) {
_WS.send("/" + clicked_id);
@ -108,61 +146,15 @@
showlissaUI();
}
if (clicked_id === "vj/vjUI") {
showlissaUI();
showvjUI();
}
if (clicked_id === "words/wordsUI") {
showwordsUI();
}
if (clicked_id === "nozoid/down 50") {
var x = document.getElementById("nozoid/down 50");
x.value = 0 ;
}
}
//
// SimuUIs
//
function nosimuUI() {
// Hide all possible main central grids.
var x = document.getElementById("planetUI");
x.style.display = "none";
var x = document.getElementById("nozoidUI");
x.style.display = "none";
var x = document.getElementById("aiUI");
x.style.display = "none";
var x = document.getElementById("lissaUI");
x.style.display = "none";
var x = document.getElementById("vjUI");
x.style.display = "none";
}
function showplanetUI() {
nosimuUI();
var x = document.getElementById("planetUI");
x.style.display = "grid";
}
function shownozoidUI() {
nosimuUI();
var x = document.getElementById("nozoidUI");
x.style.display = "grid";
}
function showaiUI() {
nosimuUI();
var x = document.getElementById("aiUI");
x.style.display = "grid";
}
function showlissaUI() {
nosimuUI();
var x = document.getElementById("lissaUI");
x.style.display = "grid";
}
function showvjUI() {
nosimuUI();
var x = document.getElementById("vjUI");
x.style.display = "grid";
}

View File

@ -1,4 +1,3 @@
.maingrid {
display: grid;
grid-template-columns: 900px;
@ -21,7 +20,7 @@
}
.mgstatus {
display: grid;
grid-template-columns: 470px 80px 1fr;
grid-template-columns: 390px 150px 1fr;
grid-template-raw: 30px;
grid-column-gap: 1px;
grid-row-gap: 1px;
@ -58,8 +57,8 @@
display: none;
height: 400px;
width: 400px;
grid-template-columns: 66px 66px 66px 66px;
grid-template-rows: 66px 17px 69px 17px;
grid-template-columns: 66px 66px 66px 66px 66px 66px;
grid-template-rows: 67px 67px 67px;
background-color: #000;
justify-items: center;
align-items: center;
@ -338,6 +337,15 @@
font: normal normal normal 11px arial;
text-decoration: none;
}
.info {
background: #000;
color: #c0c0c0;
width: 160px;
text-align: center;
vertical-align: middle;
height: 21px;
border: 1px solid #445;
}
.submit {
background: #000;
color: #c0c0c0;

View File

@ -60,29 +60,29 @@
<!-- Lasers state grid -->
<div class="lsttgrid">
<div></div>
<div></div>
<div class="lasertextxs">S</div>
<div></div>
<div></div>
<div class="lasertextxs">S</div>
<div class="lasertextxs">C</div>
<div class="lasertextxs">0</div>
<div></div>
<div class="lasertextxs">0</div>
<div></div>
<div><webaudio-knob id="lstt/0" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
<div><webaudio-knob id="lack/0" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
<div class="lasertextxs">1</div>
<div></div>
<div></div>
<div><webaudio-knob id="lstt/1" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
<div><webaudio-knob id="lack/1" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
<div class="lasertextxs">2</div>
<div></div>
<div></div>
<div><webaudio-knob id="lstt/2" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
<div><webaudio-knob id="lack/2" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
<div class="lasertextxs">3</div>
<div></div>
<div class="lasertextxs">3</div>
<div></div>
<div><webaudio-knob id="lstt/3" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
<div><webaudio-knob id="lack/3" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob></div>
</div>
@ -92,6 +92,7 @@
<div class="lasertextxs">Emergy Black</div>
<div><webaudio-switch id="emergency" height="64" width="64" value="0" src="knobs/blackout.png" type="toggle"></webaudio-switch></div>
</div>
<div>
<div class="topgrid">
@ -141,54 +142,50 @@
<div id="mgstatus" class="mgstatus">
<div>
<!-- <webaudio-switch id="align" height="10" width="99" value="0" src="knobs/align.png" type="toggle"></webaudio-switch>
<webaudio-switch id="simu" height="10" width="99" value="0" src="knobs/simu.png" type="toggle"></webaudio-switch>
<webaudio-switch id="run" height="10" width="99" value="0" src="knobs/run.png" type="toggle"></webaudio-switch>
<webaudio-switch id="live" height="10" width="99" value="0" src="knobs/live.png" type="toggle"></webaudio-switch> -->
<webaudio-switch id="align" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/align.png"></webaudio-switch>
<webaudio-switch id="simu" value="1" height="27" width="75" tooltip="Switch-B" src="knobs/simu.png"></webaudio-switch>
<webaudio-switch id="live" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/live.png"></webaudio-switch>
<webaudio-switch id="run" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/run.png"></webaudio-switch>
<webaudio-switch id="planet" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/planet.png"></webaudio-switch>
<webaudio-switch id="nozoid" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/nozoid.png"></webaudio-switch>
<webaudio-switch id="pysimu/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/pysimu.png"></webaudio-switch>
<!--
<button class="button" id="showrun" onclick="showRun()">Run</button>
<button class="button" id="shownozoid" onclick="showNozoid()">Nozoid</button>
<button class="button" id="showplanet" onclick="showPlanet()">Planet</button>
-->
</div>
<div><button class="submit" id="showstatus">OFFLINE</button></div>
<div><button class="info" id="showstatus">OFFLINE</button></div>
<div>
<div>
<span class="lasertext">Client</span>
<select onclick="buttonClicked(this.value)">
<option value="noteon 0 selected="selected" ">0</option>
<span class="lasertext">Virtual</span>
<select onclick="buttonClicked(this.value) value="0">
<option value="noteon 0">0</option>
<option value="noteon 1">1</option>
<option value="noteon 2">2</option>
<option value="noteon 3">3</option>
</select>
<span class="lasertext">PL</span>
<select onclick="buttonClicked(this.value)">
<option value="noteon 24" selected="selected" >0</option>
<option value="noteon 25">1</option>
<option value="noteon 26">2</option>
<option value="noteon 27">3</option>
</select>
<span class="lasertext">Laser</span>
<select onclick="buttonClicked(this.value)">
<option value="noteon 24" selected="selected" >0</option>
<option value="noteon 25">1</option>
<option value="noteon 26">2</option>
<option value="noteon 27">3</option>
</select>
<span class="lasertext">PL</span>
<select onclick="buttonClicked(this.value)">
<option value="planet/planetUI" selected="selected" >Planetarium</option>
<option value="noteon 24">0</option>
<option value="noteon 25">1</option>
<option value="noteon 26">2</option>
<option value="noteon 27">3</option>
</select>
<!--
<span class="lasertext">Laser</span>
<select onclick="buttonClicked(this.value)">
<option value="noteon 24" selected >0</option>
<option value="noteon 25">1</option>
<option value="noteon 26">2</option>
<option value="noteon 27">3</option>
</select>
-->
<select onclick="buttonClicked(this.value)" value="planet/planetUI">
<option value="planet/planetUI">Planetarium</option>
<option value="nozoid/nozoidUI">Nozoid</option>
<option value="vj/vjUI">VJing</option>
<option value="bank0/vjUI">VJing</option>
<option value="words/wordsUI">Words</option>
<option value="ai/aiUI">AI</option>
<option value="lissa/lissaUI">Lissa</option>
</select>
@ -536,7 +533,18 @@
<div id ="planetUI" style = "display: grid;justify-items: center;">
<!-- Stop and start switch -->
<div>
<div><webaudio-switch id="planet/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/planet.png"></webaudio-switch></div>
<div><webaudio-switch id="planet/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/planet.png"></webaudio-switch>
</div>
<div>
<span class="lasertext">Virtual</span>
<select onclick="buttonClicked(this.value)">
<option value="planet/ljclient 0" selected >0</option>
<option value="planet/ljclient 1">1</option>
<option value="planet/ljclient 2">2</option>
<option value="planet/ljclient 3">3</option>
</select>
</div>
</div>
<form onsubmit="onSubmit(); return false;">
@ -658,14 +666,106 @@
<!-- sub right part : vjUI -->
<div id ="vjUI" style = "display: none;justify-items: center;">
<!-- VJ Interface -->
<!-- Stop and start switch -->
<div><webaudio-switch id="vj/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/live.png"></webaudio-switch></div>
<div id ="vjUI" class="cnvbuttons">
<div><webaudio-switch id="bank 0" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="bank 1" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch>></div>
<div><webaudio-switch id="bank 2" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="bank 3" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="bank 4" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="bank 5" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch>></div>
<div><webaudio-switch id="noteon 26" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 27" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 24" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 25" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch>></div>
<div><webaudio-switch id="noteon 26" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 27" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 26" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 27" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 24" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 25" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch>></div>
<div><webaudio-switch id="noteon 26" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
<div><webaudio-switch id="noteon 27" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/iconvj1.png"></webaudio-switch></div>
</div>
<!-- sub right part : wordsUI -->
<div id ="wordsUI" style = "display: none;justify-items: center;">
<div>
<webaudio-switch id="words/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/words.png"></webaudio-switch>
<span class="lasertext">Virtual</span>
<select onclick="buttonClicked(this.value)">
<option value="words/ljclient 0" selected >0</option>
<option value="words/ljclient 1">1</option>
<option value="words/ljclient 2">2</option>
<option value="words/ljclient 3">3</option>
</select>
</div>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 0 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/0">
<span class="lasertext">Color</span>
<select onclick="buttonClicked(this.value)">
<option value="words/0 red" selected >Red</option>
<option value="words/0 green">Green</option>
<option value="words/0 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
</select>
</form>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 1 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/1">
<span class="lasertext">Color</span>
<select onclick="buttonClicked(this.value)">
<option value="words/1 red" selected >Red</option>
<option value="words/1 green">Green</option>
<option value="words/1 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
</select>
</form>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 2 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/2">
<span class="lasertext">Color</span>
<select onclick="buttonClicked(this.value)">
<option value="words/2 red" selected >Red</option>
<option value="words/2 green">Green</option>
<option value="words/2 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
</select>
</form>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 3 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/3">
<span class="lasertext">Color</span>
<select onclick="buttonClicked(this.value)">
<option value="words/3 red" selected >Red</option>
<option value="words/3 green">Green</option>
<option value="words/3 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
</select>
</form>
</div>
<!-- sub right part : NozoidUI -->
<div id ="nozoidUI" style = "display: none;justify-items: center;">
@ -677,14 +777,20 @@
<div>
<!-- Nozoids list and leds -->
<div>
<webaudio-switch id="nozoid/mmo3" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/mmo3.png"></webaudio-switch>
<webaudio-knob id="nozoid/mmo3/led" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob>
<webaudio-switch id="nozoid/mmo3" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/mmo3.png"></webaudio-switch>
<webaudio-switch id="nozoid/mmo3/down 50" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/slower.png"></webaudio-switch>
<webaudio-switch id="nozoid/mmo3/up 50" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/faster.png"></webaudio-switch>
<webaudio-switch id="nozoid/ocs2" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/ocs2.png"></webaudio-switch>
<div></div>
<webaudio-knob id="nozoid/ocs2/led" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob>
<webaudio-switch id="nozoid/ocs2" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/ocs2.png"></webaudio-switch>
<webaudio-switch id="nozoid/ocs2/down 50" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/slower.png"></webaudio-switch>
<webaudio-switch id="nozoid/ocs2/up 50" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/faster.png"></webaudio-switch>
</div>
<!-- Curve choice -->
<div>
<span class="lasertext" >Curve</span>
@ -709,85 +815,85 @@
<!-- X curve Line IN and X Curve choices -->
<div>
<span class="lasertext" >X : LineIN</span>
<span class="lasertext" >X</span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/X/IN 0">STOP</option>
<option value="nozoid/X/IN 1">VCO1</option>
<option value="nozoid/X/IN 2">VCO2</option>
<option value="nozoid/X/IN 3">LFO1</option>
<option value="nozoid/X/IN 4">LFO2</option>
<option value="nozoid/X/IN 5">LFO3</option>
<option value="nozoid/X/IN 6">CV/GEN</option>
<option value="nozoid/X/IN 7">ADSR</option>
<option value="nozoid/X/IN 8">LIGHT</option>
<option value="nozoid/X/IN 9">LINE IN</option>
<option value="nozoid/X/IN 10">MIDI</option>
<option value="nozoid/X/IN 11">CV1</option>
<option value="nozoid/X/IN 12">CV2</option>
<option value="nozoid/X/IN 13">CV3</option>
<option value="nozoid/X/IN 17">1 Out</option>
<option value="nozoid/X/IN 18">2 Out</option>
<option value="nozoid/X/IN 20">VCF</option>
<option value="nozoid/X/IN 21">MIX</option>
<option value="nozoid/X/IN 22">VCA</option>
<option value="nozoid/X 0">STOP</option>
<option value="nozoid/X 1">VCO1</option>
<option value="nozoid/X 2">VCO2</option>
<option value="nozoid/X 3">LFO1</option>
<option value="nozoid/X 4">LFO2</option>
<option value="nozoid/X 5">LFO3</option>
<option value="nozoid/X 6">CV/GEN</option>
<option value="nozoid/X 7">ADSR</option>
<option value="nozoid/X 8">LIGHT</option>
<option value="nozoid/X 9">LINE IN</option>
<option value="nozoid/X 10">MIDI</option>
<option value="nozoid/X 11">CV1</option>
<option value="nozoid/X 12">CV2</option>
<option value="nozoid/X 13">CV3</option>
<option value="nozoid/X 17">1 Out</option>
<option value="nozoid/X 18">2 Out</option>
<option value="nozoid/X 20">VCF</option>
<option value="nozoid/X 21">MIX</option>
<option value="nozoid/X 22">VCA</option>
</select>
<span class="lasertext" >Curve</span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/X/IN 0">Stop</option>
<option value="nozoid/X/IN 1">OSC1</option>
<option value="nozoid/X/IN 2">OSC2</option>
<option value="nozoid/X/IN 3">OSC3</option>
<option value="nozoid/X/IN 4">LFO1</option>
<option value="nozoid/X/IN 5">LFO2</option>
<option value="nozoid/X/IN 6">LFO3</option>
<option value="nozoid/X/IN 7">ADSR</option>
<option value="nozoid/X/IN 8">CV</option>
<option value="nozoid/X/IN 9">Line IN</option>
<option value="nozoid/X/IN 10">Jstck</option>
<option value="nozoid/X/IN 11">INL</option>
<option value="nozoid/X/IN 12">INR</option>
<option value="nozoid/X 0">Stop</option>
<option value="nozoid/X 1">OSC1</option>
<option value="nozoid/X 2">OSC2</option>
<option value="nozoid/X 3">OSC3</option>
<option value="nozoid/X 4">LFO1</option>
<option value="nozoid/X 5">LFO2</option>
<option value="nozoid/X 6">LFO3</option>
<option value="nozoid/X 7">ADSR</option>
<option value="nozoid/X 8">CV</option>
<option value="nozoid/X 9">Line IN</option>
<option value="nozoid/X 10">Jstck</option>
<option value="nozoid/X 11">INL</option>
<option value="nozoid/X 12">INR</option>
</select>
</div>
<!-- Y curve Line IN and Y Curve choices -->
<div>
<span class="lasertext" >Y : LineIN</span>
<span class="lasertext" >Y</span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/Y/IN 0">STOP</option>
<option value="nozoid/Y/IN 1">VCO1</option>
<option value="nozoid/Y/IN 2">VCO2</option>
<option value="nozoid/Y/IN 3">LFO1</option>
<option value="nozoid/Y/IN 4">LFO2</option>
<option value="nozoid/Y/IN 5">LFO3</option>
<option value="nozoid/Y/IN 6">CV/GEN</option>
<option value="nozoid/Y/IN 7">ADSR</option>
<option value="nozoid/Y/IN 8">LIGHT</option>
<option value="nozoid/Y/IN 9">LINE IN</option>
<option value="nozoid/Y/IN 10">MIDI</option>
<option value="nozoid/Y/IN 11">CV1</option>
<option value="nozoid/Y/IN 12">CV2</option>
<option value="nozoid/Y/IN 13">CV3</option>
<option value="nozoid/Y/IN 17">1 Out</option>
<option value="nozoid/Y/IN 18">2 Out</option>
<option value="nozoid/Y/IN 20">VCF</option>
<option value="nozoid/Y/IN 21">MIX</option>
<option value="nozoid/Y/IN 22">VCA</option>
<option value="nozoid/Y 0">STOP</option>
<option value="nozoid/Y 1">VCO1</option>
<option value="nozoid/Y 2">VCO2</option>
<option value="nozoid/Y 3">LFO1</option>
<option value="nozoid/Y 4">LFO2</option>
<option value="nozoid/Y 5">LFO3</option>
<option value="nozoid/Y 6">CV/GEN</option>
<option value="nozoid/Y 7">ADSR</option>
<option value="nozoid/Y 8">LIGHT</option>
<option value="nozoid/Y 9">LINE IN</option>
<option value="nozoid/Y 10">MIDI</option>
<option value="nozoid/Y 11">CV1</option>
<option value="nozoid/Y 12">CV2</option>
<option value="nozoid/Y 13">CV3</option>
<option value="nozoid/Y 17">1 Out</option>
<option value="nozoid/Y 18">2 Out</option>
<option value="nozoid/Y 20">VCF</option>
<option value="nozoid/Y 21">MIX</option>
<option value="nozoid/Y 22">VCA</option>
</select>
<span class="lasertext" >Curve</span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/Y/IN 0">Stop</option>
<option value="nozoid/Y/IN 1">OSC1</option>
<option value="nozoid/Y/IN 2">OSC2</option>
<option value="nozoid/Y/IN 3">OSC3</option>
<option value="nozoid/Y/IN 4">LFO1</option>
<option value="nozoid/Y/IN 5">LFO2</option>
<option value="nozoid/Y/IN 6">LFO3</option>
<option value="nozoid/Y/IN 7">ADSR</option>
<option value="nozoid/Y/IN 8">CV</option>
<option value="nozoid/Y/IN 9">Line IN</option>
<option value="nozoid/Y/IN 10">Jstck</option>
<option value="nozoid/Y/IN 11">INL</option>
<option value="nozoid/X/IN 12">INR</option>
<option value="nozoid/Y 0">Stop</option>
<option value="nozoid/Y 1">OSC1</option>
<option value="nozoid/Y 2">OSC2</option>
<option value="nozoid/Y 3">OSC3</option>
<option value="nozoid/Y 4">LFO1</option>
<option value="nozoid/Y 5">LFO2</option>
<option value="nozoid/Y 6">LFO3</option>
<option value="nozoid/Y 7">ADSR</option>
<option value="nozoid/Y 8">CV</option>
<option value="nozoid/Y 9">Line IN</option>
<option value="nozoid/Y 10">Jstck</option>
<option value="nozoid/Y 11">INL</option>
<option value="nozoid/X 12">INR</option>
</select>
</div>
@ -814,35 +920,13 @@
</select>
</div>
<!-- Nozoid speed UP and Down -->
<div>
<webaudio-switch id="nozoid/down 50" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/slower.png"></webaudio-switch>
<webaudio-switch id="nozoid/up 50" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/faster.png"></webaudio-switch>
</div>
</div>
</div>
</div>
<!-- Selection buttons grid
<div id="cnvbuttons" class="cnvbuttons">
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 0" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 1" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 2" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 3" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 24" onclick ="buttonClicked(this.id)" class="button:checked">PL 0</button></div>
<div><button id ="noteon 25" onclick ="buttonClicked(this.id)" class="button">PL 1</button></div>
<div><button id ="noteon 26" onclick ="buttonClicked(this.id)" class="button">PL 2</button></div>
<div><button id ="noteon 27" onclick ="buttonClicked(this.id)" class="button">PL 3</button></div>
</div>
-->
</div>
@ -925,142 +1009,6 @@
<div></div>
</div>
<!--
Nozoid
todo : buttons stop/start, stopX, stop Y
Colors
Curve
-->
<div id = "mgnozoid" class="mgnozoid">
<div>
<div>
<div>
<span class="lasertext" >MMO-3</span>
<webaudio-knob id="mmo3" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob>
</div>
<div>
<span class="lasertext" >OCS-2</span>
<webaudio-knob id="ocs2" src="knobs/leds.png" height="17" width="17" diameter="17" min="0" max="6" value="0" sprites="6"></webaudio-knob>
</div>
</div>
<div>
<div><webaudio-switch id="Start" value="0" height="76" width="76" tooltip="Switch-B" src="knobs/switch_toggle.png"></webaudio-switch></div>
<span class="lasertext" >STOP/START</span>
</div>
<div>
<span class="lasertext" >Color ? </span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/color 255 0 0">Red</option>
<option value="nozoid/color 0 255 0">Green</option>
<option value="nozoid/color 0 0 255">Blue</option>
<option value="nozoid/color 255 255 0">Yellow</option>
<option value="nozoid/color 0 255 255">Cyan</option>
<option value="nozoid/color 255 0 255">Magenta</option>
</select>
</div>
<div>
<span class="lasertext" >XCURVE LineIN</span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/X/IN 0">STOP</option>
<option value="nozoid/X/IN 1">VCO1</option>
<option value="nozoid/X/IN 2">VCO2</option>
<option value="nozoid/X/IN 3">LFO1</option>
<option value="nozoid/X/IN 4">LFO2</option>
<option value="nozoid/X/IN 5">LFO3</option>
<option value="nozoid/X/IN 6">CV/GEN</option>
<option value="nozoid/X/IN 7">ADSR</option>
<option value="nozoid/X/IN 8">LIGHT</option>
<option value="nozoid/X/IN 9">LINE IN</option>
<option value="nozoid/X/IN 10">MIDI</option>
<option value="nozoid/X/IN 11">CV1</option>
<option value="nozoid/X/IN 12">CV2</option>
<option value="nozoid/X/IN 13">CV3</option>
<option value="nozoid/X/IN 17">1 Out</option>
<option value="nozoid/X/IN 18">2 Out</option>
<option value="nozoid/X/IN 20">VCF</option>
<option value="nozoid/X/IN 21">MIX</option>
<option value="nozoid/X/IN 22">VCA</option>
</select>
<span class="lasertext" >XCURVE</span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/X/IN 0">Stop</option>
<option value="nozoid/X/IN 1">OSC1</option>
<option value="nozoid/X/IN 2">OSC2</option>
<option value="nozoid/X/IN 3">OSC3</option>
<option value="nozoid/X/IN 4">LFO1</option>
<option value="nozoid/X/IN 5">LFO2</option>
<option value="nozoid/X/IN 6">LFO3</option>
<option value="nozoid/X/IN 7">ADSR</option>
<option value="nozoid/X/IN 8">CV</option>
<option value="nozoid/X/IN 9">Line IN</option>
<option value="nozoid/X/IN 10">Jstck</option>
<option value="nozoid/X/IN 11">INL</option>
<option value="nozoid/X/IN 12">INR</option>
</select>
</div>
<div>
<span class="lasertext" >Automodulation X ? </span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/auto/X/0">0</option>
<option value="nozoid/auto/X/1 Out">1 Out</option>
<option value="nozoid/auto/X/2 Out">2 Out</option>
<option value="nozoid/auto/X/3 Out">3 Out</option>
<option value="nozoid/auto/X/OutR">OutR</option>
<option value="nozoid/auto/X/OutL">OutL</option>
</select>
<span class="lasertext">Automodulation Y ? </span>
<select onclick="buttonClicked(this.value)">
<option value="nozoid/auto/Y/0">0</option>
<option value="nozoid/auto/Y/1 Out">1 Out</option>
<option value="nozoid/auto/Y/2 Out">2 Out</option>
<option value="nozoid/auto/Y/3 Out">3 Out</option>
<option value="nozoid/auto/Y/OutR">OutR</option>
<option value="nozoid/auto/Y/OutL">OutL</option>
</select>
</div>
</div>
</div>
<!--
Planetarium
-->
<div id = "mgplanet" class="mgplanet">
<!-- Simuator canvas -->
<div>
<canvas id="canvas" width="500" height="400" style="border-color: #445;border-style:groove;border-width:1px;"></canvas>
</div>
<!-- Selection buttons grid -->
<div id="cnvbuttons" class="cnvbuttons">
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/client.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 0" onclick ="buttonClicked(this.id)" class="button:checked">0</button></div>
<div><button id ="noteon 1" onclick ="buttonClicked(this.id)" class="button">1</button></div>
<div><button id ="noteon 2" onclick ="buttonClicked(this.id)" class="button">2</button></div>
<div><button id ="noteon 3" onclick ="buttonClicked(this.id)" class="button">3</button></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><img src="knobs/iconljay2.png" alt=" " class="icongrid" /></div>
<div><button id ="noteon 24" onclick ="buttonClicked(this.id)" class="button:checked">PL 0</button></div>
<div><button id ="noteon 25" onclick ="buttonClicked(this.id)" class="button">PL 1</button></div>
<div><button id ="noteon 26" onclick ="buttonClicked(this.id)" class="button">PL 2</button></div>
<div><button id ="noteon 27" onclick ="buttonClicked(this.id)" class="button">PL 3</button></div>
</div>
</div>
<!--
Footer display events for debug
-->
@ -1077,6 +1025,7 @@
<!--
web audio buttons scripts
-->
<script type="text/javascript">
var message="";
var log=[];
@ -1121,9 +1070,6 @@
if (e.target.id === "nozoid" && e.type === "change") {
showNozoid();
}
if (e.target.id === "planet" && e.type === "change") {
showPlanet();
}
if (e.target.id === "run" && e.type === "change") {
showRun();
}
@ -1137,6 +1083,7 @@
if (e.target.id === "noteon" && e.type ==="input")
console.log("only noteon change are sent not input");
else
_WS.send("/" + e.target.id + " " + e.target.value);
@ -1162,6 +1109,7 @@
<!--
Simulator Point lists drawing scripts
-->
<script type="text/javascript">
//
@ -1286,7 +1234,7 @@
</script>
</body>
<!-- non displayed items, for code reference mainly for other type of webaudio buttons
<!-- non displayed items, for code reference mainly for other type of webaudio buttons
<div>
<span class="lasertext">Swap X</span>
<span class="lasertext">Swap Y</span>

BIN
webui/knobs/lissa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
webui/knobs/onoff2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
webui/knobs/pysimu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
webui/knobs/withai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
webui/knobs/words.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB