forked from protonphoton/LJ
Plugins mamagement
This commit is contained in:
parent
9ecee93b43
commit
c27151ec62
19
LJ.conf
19
LJ.conf
@ -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"}
|
||||
}
|
||||
|
||||
|
26
README.md
26
README.md
@ -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
6
cli.py
@ -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
|
||||
|
||||
|
||||
|
@ -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,9 +152,18 @@ def Run():
|
||||
Left = []
|
||||
Right = []
|
||||
counter =0
|
||||
WebStatus("LaserGlyph")
|
||||
|
||||
# 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)
|
||||
|
||||
try:
|
||||
|
||||
while 1:
|
||||
|
||||
Left = []
|
||||
Right = []
|
||||
|
||||
@ -156,23 +187,23 @@ def Run():
|
||||
y = vertices[point][1]
|
||||
z = vertices[point][2]
|
||||
|
||||
Left.append( Proj(x+LeftShift(z*25),y,z,0,counter,0))
|
||||
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
|
||||
lj.PolyLineOneColor(Left, c = red, PL = 0, closed = True)
|
||||
lj.PolyLineOneColor(Right, c = green, PL = 0, closed = True)
|
||||
lj.DrawPL(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
|
||||
lj.PolyLineOneColor(Left, c = red, PL = 1, closed = True)
|
||||
lj.PolyLineOneColor(Right, c = green, PL = 2, closed = True)
|
||||
lj.DrawPL(1)
|
||||
lj.DrawPL(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)
|
||||
|
||||
'''
|
||||
|
||||
@ -182,6 +213,21 @@ def Run():
|
||||
if counter >360:
|
||||
counter =0
|
||||
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
# Gently stop on CTRL C
|
||||
|
||||
finally:
|
||||
|
||||
WebStatus("Glyph Exit")
|
||||
print("Stopping OSC...")
|
||||
lj3.OSCstop()
|
||||
pass
|
||||
|
||||
print ("LaserGlyph Stopped.")
|
||||
|
||||
|
||||
white = rgb2int(255,255,255)
|
||||
red = rgb2int(255,0,0)
|
||||
blue = rgb2int(0,0,255)
|
||||
|
@ -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()
|
||||
|
||||
|
21
commands.py
21
commands.py
@ -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" :
|
||||
# 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] == "client":
|
||||
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)
|
||||
|
||||
|
4
gstt.py
4
gstt.py
@ -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
|
||||
|
167
main.py
167
main.py
@ -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 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:
|
||||
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,24 +435,17 @@ 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:
|
||||
sendextosc("/off")
|
||||
|
||||
sendbank0(oscpath[0], oscargs=oscpath[1])
|
||||
else:
|
||||
args[0] = "noargs"
|
||||
commands.handler(oscpath[0].split("/"),args)
|
||||
sendWSall("/status Bank0 offline")
|
||||
'''
|
||||
|
||||
|
||||
# if needed a loop back : WS Client -> server -> WS Client
|
||||
@ -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
181
plugins.py
Normal 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
706
plugins/VJing/bank0.py
Normal 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
618
plugins/VJing/lj3.py
Normal 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
1
plugins/VJing/poses
Symbolic link
@ -0,0 +1 @@
|
||||
../../../LJay/poses
|
598
plugins/VJing/poses.py
Normal file
598
plugins/VJing/poses.py
Normal 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
154
plugins/livewords.py
Normal 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
620
plugins/lj3.py
Normal 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)
|
||||
|
||||
|
||||
|
||||
|
89
plugins/planetarium/data/boundaries2.txt
Normal file
89
plugins/planetarium/data/boundaries2.txt
Normal 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
245
plugins/simu.py
Executable 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
130
plugins/textcycl.py
Normal 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()
|
||||
|
||||
|
@ -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')
|
||||
|
BIN
visualiser-linux
BIN
visualiser-linux
Binary file not shown.
138
webui/LJ.js
138
webui/LJ.js
@ -15,10 +15,6 @@
|
||||
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() {
|
||||
@ -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 ;
|
||||
|
||||
//
|
||||
// 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 showPlanet() {
|
||||
noMenu();
|
||||
var x = document.getElementById("mgplanet");
|
||||
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,7 +146,10 @@
|
||||
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");
|
||||
@ -117,55 +158,6 @@
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Forms submits
|
||||
|
@ -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;
|
||||
|
460
webui/index.html
460
webui/index.html
@ -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,29 +142,23 @@
|
||||
|
||||
<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>
|
||||
@ -171,24 +166,26 @@
|
||||
|
||||
<span class="lasertext">PL</span>
|
||||
<select onclick="buttonClicked(this.value)">
|
||||
<option value="noteon 24" selected="selected" >0</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="selected" >0</option>
|
||||
<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)">
|
||||
<option value="planet/planetUI" selected="selected" >Planetarium</option>
|
||||
<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,10 +666,102 @@
|
||||
|
||||
<!-- 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>
|
||||
|
||||
|
||||
@ -677,13 +777,19 @@
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
@ -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
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
BIN
webui/knobs/onoff2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
webui/knobs/pysimu.png
Normal file
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
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
BIN
webui/knobs/words.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
Loading…
Reference in New Issue
Block a user