Plugins mamagement

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

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

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

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

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

1
plugins/VJing/poses Symbolic link
View file

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

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

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

View file

@ -0,0 +1,255 @@
"""
Directions Buttons defined correctly only for PS3 and USBJoystick
Represent various videogame controllers
TODO: Various play schemes/configs
XXX: UNTESTED
"""
import re
def setup_controls(joystick):
"""
Joystick wrapper.
"""
if re.search('playstation', joystick.get_name(), re.I):
return Ps3Controller(joystick)
elif re.search('X-box', joystick.get_name(), re.I):
return XboxController(joystick)
elif re.search('Saitek', joystick.get_name(), re.I):
return MySaitekController(joystick)
elif re.search('Thrustmaster dual analog 3.2', joystick.get_name(), re.I):
return MyThrustController(joystick)
elif re.search('2n1 USB', joystick.get_name(), re.I):
return CSLController(joystick)
elif re.search('Joystick', joystick.get_name(), re.I):
return USBController(joystick)
return Controller(joystick)
class Controller(object):
def __init__(self, joystick):
"""Pass a PyGame joystick instance."""
self.js = joystick
def getLeftHori(self):
return self.js.get_axis(2)
def getLeftVert(self):
return self.js.get_axis(3)
def getRightHori(self):
return self.js.get_axis(0)
def getRightVert(self):
return self.js.get_axis(1)
def getLeftTrigger(self):
return self.js.get_button(9)
def getRightTrigger(self):
return self.js.get_button(2)
class XboxController(Controller):
def __init__(self, joystick):
super(XboxController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(3)
def getRightVert(self):
return self.js.get_axis(4)
def getLeftTrigger(self):
return self.js.get_axis(2)
def getRightTrigger(self):
return self.js.get_button(11)
class Ps3Controller(Controller):
#up 4 _DOWN 6 left 7 right 5 croix 14 rond 13 triangle 12
def __init__(self, joystick):
super(Ps3Controller, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(2)
def getRightVert(self):
return self.js.get_axis(3)
def getLeftTrigger(self):
# TODO: Verify
return self.js.get_button(8)
def getRightTrigger(self):
# TODO: Verify
return self.js.get_button(9)
def getUp(self):
return self.js.get_button(4)
def getDown(self):
return self.js.get_button(6)
def getLeft(self):
return self.js.get_button(7)
def getRight(self):
return self.js.get_button(5)
def getFire1(self):
return self.js.get_button(14)
def getFire2(self):
return self.js.get_button(13)
class MySaitekController(Controller):
def __init__(self, joystick):
super(MySaitekController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(3)
def getRightVert(self):
return self.js.get_axis(2)
def getLeftTrigger(self):
return self.js.get_button(6)
def getRightTrigger(self):
return self.js.get_button(7)
class MyThrustController(Controller):
def __init__(self, joystick):
super(MyThrustController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(0)
def getLeftVert(self):
return self.js.get_axis(1)
def getRightHori(self):
return self.js.get_axis(2)
def getRightVert(self):
return self.js.get_axis(3)
def getLeftTrigger(self):
return self.js.get_button(5)
def getRightTrigger(self):
return self.js.get_button(7)
class CSLController(Controller):
def __init__(self, joystick):
super(CSLController, self).__init__(joystick)
def getLeftHori(self):
return self.js.get_axis(2)
def getLeftVert(self):
return self.js.get_axis(3)
def getRightHori(self):
return self.js.get_axis(0)
def getRightVert(self):
return self.js.get_axis(1)
def getLeftTrigger(self):
return self.js.get_button(6)
def getRightTrigger(self):
return self.js.get_button(7)
def getFire1(self):
return self.js.get_button(2)
def getFire2(self):
return self.js.get_button(1)
class USBController(Controller):
# my USB Joystick
#up axis 0 -1 DOWN axis 0 1 left axis 1 1 right axis 1 -1 bouton gauche 10 bouton droite 9
def __init__(self, joystick):
super(USBController, self).__init__(joystick)
def getUp(self):
if self.js.get_axis(0) == -1:
return 1
else:
return 0
def getDown(self):
if self.js.get_axis(0) > 0.9:
return 1
else:
return 0
def getLeft(self):
if self.js.get_axis(1) == 1:
return 1
else:
return 0
def getRight(self):
if self.js.get_axis(1) == -1:
return 1
else:
return 0
def getLeftTrigger(self):
return self.js.get_button(10)
def getRightTrigger(self):
return self.js.get_button(9)
def getFire1(self):
if self.js.get_button(10) == 1:
print "fire 1"
return self.js.get_button(10)
def getFire2(self):
if self.js.get_button(9) == 1:
print "fire 2"
return self.js.get_button(9)

View file

@ -0,0 +1,259 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
LJ Laser Pong entities
v0.1
Sam Neurohack
'''
# STDLIB
import math
import itertools
import sys
import os
import lj
import time
import random
screen_size = [800,600]
top_left = [200,100]
bottom_left = [200,300]
top_right = [600,100]
bottom_right = [600,300]
score_pos = [550,40]
score2_pos = [259,40]
# X Y position on bottom left of each paddle (="flips")
ball_origin = [400,300,200]
text_pos = [300,500,200]
BALL_acc = 0.06
PADDLE_height = 100
PADDLE_width = 10
PADDLE3D_height = 100
PADDLE3D_width = 100
FACT3D = 2
FLIPS_lorigin = [10,300,0]
FLIPS_rorigin = [780,300,400]
flips_attraction = 0.007
xy_center = [screen_size[0]/2,screen_size[1]/2]
DEFAULT_SPOKES = range(0,359,60)
DEFAULT_PLAYER_EXPLODE_COLOR = 0xFFFF00
DEFAULT_SIDE_COUNT = 6
DREARRANGE_SIDES = .02
CRASH_SHAKE_MAX = 6
TDN_CRASH = 200
GAME_FS_QUIT = -1
GAME_FS_MENU = 0
GAME_FS_PLAY = 1
GAME_FS_LAUNCH = 2
GAME_FS_GAMEOVER = 3
BUMPERS_COLOR_YELLOW = 0xFFFF00
BUMPERS_COLOR_RED = 0xFF0000
BUMPERS_COLOR_BLACK = 0x000000
BUMPERS_SIZE_X = 60
BUMPERS_SIZE_Y = 110
BUMPERS_FORCE = 1.1
BALL_SPEED = 5
BALL_MAX = 4
BALL_SIZE_X = 3
BALL_SIZE_Y = 3
LASER_ANGLE = 0
GRAVITY = 0.0001
NO_BGM = False
#NO_BGM = True
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
white = rgb2int(255,255,255)
red = rgb2int(255,0,0)
blue = rgb2int(0,0,255)
green = rgb2int(0,255,0)
LOGO = [
# L/o
[[(-140,-100),(-200,20),(40,20)],0xFF00],
# aser
[[(-140,-40),(-100,-40,),(-120,0),(-160,0),(-110,-20)],0xFFFF],
[[(-40,-40),(-60,-40),(-90,-20),(-50,-20),(-80,0),(-100,0)],0xFFFF],
[[(-30,-20),(10,-20),(0,-40),(-20,-40),(-30,-20),(-30,0),(-10,0)],0xFFFF],
[[(20,0),(40,-40),(35,-30),(50,-40),(70,-40)],0xFFFF],
# Pinball
[[(-185,50),(-145,50),(-130,20),(-170,20),(-200,80)],0xFFFF00], #P
[[(-80,40),(-120,40),(-140,80),(-100,80),(-80,40)],0xFFFF], #O
[[(-80,80),(-60,40),(-65,50),(-40,40),(-25,50),(-40,80)],0xFFFF], #N
[[(40,40),(0,40),(-20,80),(20,80),(30,60),(10,60)],0xFFFF], #G
]
LOGO_OFFSET_X = 460
LOGO_OFFSET_Y = 250
def LogoDraw():
'''
Dessine le logo
'''
for pl_color in LOGO:
c = pl_color[1]
xy_list = []
for xy in pl_color[0]:
xy_list.append((LOGO_OFFSET_X + xy[0], LOGO_OFFSET_Y + xy[1]))
#print xy_list
lj.PolyLineOneColor(xy_list, c,0, False)
FlipsLx, FlipsLy = FLIPS_lorigin[0], FLIPS_lorigin[1]
FlipsRx, FlipsRy = FLIPS_rorigin[0], FLIPS_rorigin[1]
FlipsSpeed = 7
def FlipsMove(left_key,right_key,up_key,down_key):
global FlipsLx, FlipsLy, FlipsRx, FlipsRy
if left_key:
FlipsLy -= FlipsSpeed
if FlipsLy < 1:
FlipsLy = 1
if right_key:
FlipsLy += FlipsSpeed
if FlipsLy > screen_size[1] - PADDLE_height:
FlipsLy = screen_size[1] - PADDLE_height
if up_key:
FlipsRy -= FlipsSpeed
if FlipsRy < 1:
FlipsRy = 1
if down_key:
FlipsRy += FlipsSpeed
if FlipsRy > screen_size[1] - PADDLE_height:
FlipsRy = screen_size[1] - PADDLE_height
return FlipsLy, FlipsRy
def FlipsMoveJoy(left_key,right_key,up_key,down_key,lvertax):
if left_key:
FlipsLy -= FlipsSpeed
if FlipsLy < 1:
FlipsLy = 1
if right_key:
FlipsLy += FlipsSpeed
if FlipsLy > screen_size[1] - PADDLE_height:
FlipsLy = screen_size[1] - PADDLE_height
if up_key:
FlipsRy -= FlipsSpeed
if FlipsRy < 1:
FlipsRy = 1
if down_key > 0.01:
FlipsRy += FlipsSpeed
if FlipsRy > screen_size[1] - PADDLE_height:
FlipsRy = screen_size[1] - PADDLE_height
if lvertax:
print lvertax
if lvertax < 0:
FlipsLy -= FlipsSpeed
if FlipsLy < 1:
FlipsLy = 1
elif lvertax > 0.01:
FlipsLy += FlipsSpeed
if FlipsLy > screen_size[1] - PADDLE_height:
FlipsLy = screen_size[1] - PADDLE_height
return FlipsLy, FlipsRy
def FlipsDraw():
lj.PolyLineOneColor([(FlipsLx,FlipsLy),(FlipsLx,FlipsLy + PADDLE_height),(FlipsLx + PADDLE_width , FlipsLy + PADDLE_height),(FlipsLx + PADDLE_width,FlipsLy)], white,0,True)
lj.PolyLineOneColor([(FlipsRx,FlipsRy),(FlipsRx,FlipsRy + PADDLE_height),(FlipsRx + PADDLE_width , FlipsRy + PADDLE_height),(FlipsRx + PADDLE_width,FlipsRy)], white,0,True)
def FiletDraw():
lj.PolyLineOneColor([(screen_size[0]/2,screen_size[1]),(screen_size[0]/2,0)], white, 0,True)
def Score1Draw(score):
#print "score1",score
lj.Text(str(score),white, 0, 350, 50, 1, 0, 0, 0)
def Score2Draw(score):
#print "score2",score
lj.Text(str(score),white, 0, 500, 50, 1, 0, 0, 0)
BallX, BallY = ball_origin[0], ball_origin[1]
BallZoom = 1
def BallMove(xcoord,ycoord):
global BallX,BallY
BallX = xcoord
BallY = ycoord
#print "ball move",xcoord,ycoord
#BallZoom = ?
if BallX < 0:
BallX = 0
elif BallX >= screen_size[0]:
BallX = screen_size[0]
if BallY < 0:
BallY = 0
elif BallY >= screen_size[1]:
BallY = screen_size[1]
def BallDraw():
global BallX,BallY
xmin = 0
xmax = BALL_SIZE_X * 2
ymin = 0
ymax = BALL_SIZE_Y * 2
xmin = (xmin*BallZoom)
ymin = (ymin*BallZoom)
xmax = (xmax*BallZoom)
ymax = (ymax*BallZoom)
xmin += BallX
xmax += BallX
ymin += BallY
ymax += BallY
#print "ball position",xmin,xmax,ymin,ymax
lj.PolyLineOneColor([(xmin,ymin),(xmin,ymax),(xmax,ymax),(xmax,ymin)], white,0,True)

310
plugins/games/ljpong/lj.py Normal file
View file

@ -0,0 +1,310 @@
# coding=UTF-8
'''
LJ v0.8.0
Some LJ functions useful for python clients (was framy.py)
Config
PolyLineOneColor
rPolyLineOneColor
Text
sendlj : remote control
DrawPL
LICENCE : CC
Sam Neurohack
'''
import math
import redis
from OSC import OSCServer, OSCClient, OSCMessage
redisIP = '127.0.0.1'
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = 0
point_list = []
pl = [[],[],[],[]]
'''
LJIP = "127.0.0.1"
osclientlj = OSCClient()
oscmsg = OSCMessage()
osclientlj.connect((redisIP, 8002))
'''
def sendlj(oscaddress,oscargs=''):
oscmsg = OSCMessage()
oscmsg.setAddress(oscaddress)
oscmsg.append(oscargs)
#print ("sending to bhorosc : ",oscmsg)
try:
osclientlj.sendto(oscmsg, (redisIP, 8002))
oscmsg.clearData()
except:
print ('Connection to LJ refused : died ?')
pass
#time.sleep(0.001
ASCII_GRAPHICS = [
#implementé
[(-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
# 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)], #@
# Implementé
[(-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 Config(redisIP,client):
global ClientNumber
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = client
#print "client configured",ClientNumber
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 = math.radians(rotx)
cosaX = math.cos(rad)
sinaX = math.sin(rad)
y2 = y
y = y2 * cosaX - z * sinaX
z = y2 * sinaX + z * cosaX
rad = math.radians(roty)
cosaY = math.cos(rad)
sinaY = math.sin(rad)
z2 = z
z = z2 * cosaY - x * sinaY
x = z2 * sinaY + x * cosaY
rad = math.radians(rotz)
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:
#print '/pl/'+str(ClientNumber)+'/'+str(PL), str(pl[PL])
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)
# Digits
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)
#dots.append(char_draw)

367
plugins/games/ljpong/main.py Executable file
View file

@ -0,0 +1,367 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
LJ Laser Pong v0.8
Sam Neurohack
'''
import pygame
import math
import itertools
import sys
import os
'''
is_py2 = sys.version[0] == '2'
if is_py2:
from Queue import Queue
else:
from queue import Queue
'''
import thread
import time
import random
import lj
import entities
from controller import setup_controls
import argparse
score = None
screen_size = [800,600]
top_left = [200,100]
bottom_left = [200,300]
top_right = [600,100]
bottom_right = [600,300]
score_pos = [550,40]
score2_pos = [259,40]
text_pos = [300,500,200]
ball_origin = [400,300,200]
BALL_SPEED = 5
BALL_SIZE_X = 3
BALL_SIZE_Y = 3
BALL_acc = 0.06
PADDLE_height = 100
PADDLE_width = 10
FlipsSpeed = 7
FLIPS_lorigin = [10,300,0]
FLIPS_rorigin = [780,300,400]
FlipsLx, FlipsLy = FLIPS_lorigin[0], FLIPS_lorigin[1]
FlipsRx, FlipsRy = FLIPS_rorigin[0], FLIPS_rorigin[1]
xy_center = [screen_size[0]/2,screen_size[1]/2]
GAME_FS_QUIT = -1
GAME_FS_MENU = 0
GAME_FS_PLAY = 1
GAME_FS_GAMEOVER = 2
GAME_FS_LAUNCH = 2
SCORE_ZOOM_PLAYING = 1.6
SCORE_ZOOM_GAMEOVER = 5.0
SCORE_DZOOM_PLAYING = -0.4
SCORE_DZOOM_GAMEOVER = 0.1
Score1Zoom = SCORE_ZOOM_PLAYING
GRAVITY = 0.0001
fs = GAME_FS_MENU
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
white = rgb2int(255,255,255)
red = rgb2int(255,0,0)
blue = rgb2int(0,0,255)
green = rgb2int(0,255,0)
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Laserpong")
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)
def StartPlaying(first_time = False):
global fs
lscore = 0
rscore = 0
fs = GAME_FS_LAUNCH
x = ball_origin[0]
y = ball_origin[1]
app_path = os.path.dirname(os.path.realpath(__file__))
pygame.init()
#sounds.InitSounds()
clock = pygame.time.Clock()
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 = setup_controls(pad2)
if Nbpads > 0:
pad1 = pygame.joystick.Joystick(0)
pad1.init()
print "Pad1 :",pad1.get_name()
numButtons = pad1.get_numbuttons()
joy1 = setup_controls(pad1)
#print ("Axis Pad 1 :", str(pad1.get_numaxes()))
#print ("Buttons Pad 1 :" , str(numButtons))
update_screen = False
xvel = - 1
yvel = 0
lscore = 0
rscore = 0
ly = FLIPS_lorigin[1]
ry = FLIPS_rorigin[1]
flipsy = [ly, ry]
stick = 0
x = ball_origin[0]
y = ball_origin[1]
keystates = pygame.key.get_pressed()
while fs != GAME_FS_QUIT:
for event in pygame.event.get():
if event.type == pygame.QUIT:
fs = GAME_FS_QUIT
keystates_prev = keystates[:]
keystates = pygame.key.get_pressed()[:]
# Etats du jeu
if fs == GAME_FS_MENU:
if keystates[pygame.K_ESCAPE] and not keystates_prev[pygame.K_ESCAPE]:
fs = GAME_FS_QUIT
elif keystates[pygame.K_SPACE] and not keystates_prev[pygame.K_SPACE]:
StartPlaying(True)
lscore = 0
rscore = 0
if joy1.getFire1() or joy2.getFire1():
StartPlaying(False)
lscore =0
rscore = 0
elif fs == GAME_FS_PLAY:
if keystates[pygame.K_ESCAPE] and not keystates_prev[pygame.K_ESCAPE]:
fs = GAME_FS_MENU
'''
if Nbpads > 0:
print "pad 1 :", joy1.getUp(), joy1.getDown(), joy1.getLeftTrigger(),joy1.getRightTrigger()
print "pad 2 :", joy2.getUp(), joy2.getDown(), joy2.getLeftTrigger(),joy2.getRightTrigger()
'''
# Lost ball / first to ten points ?
#print " ball : " , x, y, " left : ", ly, " right : ", ry
if x < FLIPS_lorigin[0] + PADDLE_width:
print ("ball.y : ", y, " ly : ", ly)
if y > (ly + PADDLE_height + 1) or y < (ly - BALL_SIZE_Y - 1):
rscore += 1
xvel = random.uniform(-1,-0.6)
if rscore == 11:
fs = GAME_FS_MENU
else:
fs = GAME_FS_LAUNCH
else:
x = FLIPS_lorigin[0] + PADDLE_width
xvel *= -1
if x > FLIPS_rorigin[0] - PADDLE_width:
print ("ball.y : ", y, " ry : ", ry)
if y < (ry - BALL_SIZE_Y - 1) or y > (ry + PADDLE_height + 1):
lscore += 1
xvel = random.uniform(1,0.6)
if lscore == 11:
fs = GAME_FS_MENU
else:
fs = GAME_FS_LAUNCH
else:
xvel *= -1
x = FLIPS_rorigin[0] - PADDLE_width
# wall detect
if y < 0:
y = 1
yvel *= -1
if y > screen_size[1]:
y = screen_size[1] - 1
yvel *= -1
# Anim
x += BALL_SPEED * xvel
y += BALL_SPEED * yvel
yvel += GRAVITY
entities.BallMove(x,y)
if Nbpads > 0:
flipsy = entities.FlipsMove(joy1.getUp(),joy1.getDown(),joy2.getUp(),joy2.getDown())
else:
flipsy = entities.FlipsMove(keystates[pygame.K_a],keystates[pygame.K_q],keystates[pygame.K_UP],keystates[pygame.K_DOWN])
ly = flipsy[0]
ry = flipsy[1]
elif fs == GAME_FS_LAUNCH:
'''
if Nbpads > 0:
print "pad 1 :", joy1.getUp(), joy1.getDown(), joy1.getLeftTrigger(),joy1.getRightTrigger()
print "pad 2 :", joy2.getUp(), joy2.getDown(), joy2.getLeftTrigger(),joy2.getRightTrigger()
print pad1.get_axis(0),pad2.get_axis(0)
'''
if keystates[pygame.K_ESCAPE] and not keystates_prev[pygame.K_ESCAPE]:
fs = GAME_FS_MENU
if keystates[pygame.K_SPACE] and not keystates_prev[pygame.K_SPACE]:
fs = GAME_FS_PLAY
yvel = 0
while math.fabs(xvel + yvel) < 1:
#xvel = random.uniform(-1,1)
yvel = random.uniform(-1,1)
if joy1.getFire1() or joy2.getFire1():
fs = GAME_FS_PLAY
yvel = 0
while math.fabs(xvel + yvel) < 1:
#xvel = random.uniform(-1,1)
yvel = random.uniform(-1,1)
x = ball_origin[0]
y = ball_origin[1]
entities.BallMove(x,y)
if Nbpads > 0:
flipsy = entities.FlipsMove(joy1.getUp(),joy1.getDown(),joy2.getUp(),joy2.getDown())
else:
flipsy = entities.FlipsMove(keystates[pygame.K_a],keystates[pygame.K_q],keystates[pygame.K_UP],keystates[pygame.K_DOWN])
ly = flipsy[0]
ry = flipsy[1]
elif fs == GAME_FS_GAMEOVER:
#TODO : MODE GAME OVER, autres opérations d'animation
# Remarque : on peut supprimer le mode GAME OVER et le gérer dans le mode jeu
# si les traitements sont les mêmes
'''
if keystates[pygame.K_SPACE] and not keystates_prev[pygame.K_SPACE]:
StartPlaying(False)
'''
if joy1.getFire1() or joy2.getFire1():
StartPlaying(False)
elif keystates[pygame.K_ESCAPE] and not keystates_prev[pygame.K_ESCAPE]:
fs = GAME_FS_MENU
# Peut-être aussi réinitialiser l'état dans le mode menu
if fs == GAME_FS_PLAY or fs == GAME_FS_GAMEOVER or fs == GAME_FS_LAUNCH:
entities.Score1Draw(lscore)
entities.Score2Draw(rscore)
entities.FlipsDraw()
entities.BallDraw()
entities.FiletDraw()
lj.DrawPL(0)
if fs == GAME_FS_MENU:
entities.LogoDraw()
lj.DrawPL(0)
# TODO : rendre indépendante la fréquence de rafraîchissement de l'écran par
# rapport à celle de l'animation du jeu
clock.tick(100)
pygame.quit()

154
plugins/livewords.py Normal file
View file

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

620
plugins/lj3.py Normal file
View file

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

View file

@ -0,0 +1,45 @@
Multi Laser planetarium in python3 for LJ.
v0.01
Sam Neurohack
Make sure to understand altitude/azimuth coordinate system.
Display all solar planets and hipparcos catalog objects below a given magnitude. Accuracy tested against apparent data and starchart at https://www.calsky.com/cs.cgi?cha=7&sec=3&sub=2
It's an alpha release so a little hardcoded :
- set observer position (find SkyCity, SkyCountryCode) in main.py like 'Paris' and 'FR'
- set observer date/time in InitObserver() arguments (default is now in UTC)
- set what sky part you want to display for each laser in 'LaserSkies' variable : Define alitude and azimuth for top left and bottom right of each laser.
It needs more libraries than plan. Currently it relies on the awesome astropy, skyfield,...
Soon some pictures.
To Run :
Launch LJ first
python3 main.py
For debug options and more type : python3 --help
To install :
Install LJ first.
go3.sh install required python3 modules
NB :
- if you get an year error out of range : install the last skyfield "python-skyfield" in github.
- Read main.py
LICENCE : CC
Remember : LJ will automatically warp geometry according to alignement data before sending to lasers. See webUI.
'''

View file

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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
sudo apt install python3-pip
pip3 install jplephem
pip3 install pyephem
pip3 install astropy
pip3 install skyfield
pip3 install pandas
pip3 install redis
pip3 install osc4py3
pip3 install --pre astroquery

View file

@ -0,0 +1,96 @@
Acamar, 13847
Groombridge 1830, 57939
Achernar, 7588
Hadar, 68702
Acrux, 60718
Hamal, 9884
Adhara, 33579
Izar, 72105
Agena, 68702
Kapteyn's star, 24186
Albireo, 95947
Kaus Australis, 90185
Alcor, 65477
Kocab, 72607
Alcyone, 17702
Kruger,60, 110893
Aldebaran, 21421
Luyten's star, 36208
Alderamin, 105199
Markab, 113963
Algenib, 1067
Megrez, 59774
Algieba, 50583
Menkar, 14135
Algol, 14576
Merak, 53910
Alhena, 31681
Mintaka, 25930
Alioth, 62956
Mira, 10826
Alkaid, 67301
Mirach, 5447
Almaak, 9640
Mirphak, 15863
Alnair, 109268
Mizar, 65378
Alnath, 25428
Nihal, 25606
Alnilam, 26311
Nunki, 92855
Alnitak, 26727
Phad, 58001
Alphard, 46390
Pleione, 17851
Alphekka, 76267
Polaris, 11767
Alpheratz, 677
Pollux, 37826
Alshain, 98036
Procyon, 37279
Altair, 97649
Proxima, 70890
Ankaa, 2081
Rasalgethi, 84345
Antares, 80763
Rasalhague, 86032
Arcturus, 69673
Red,Rectangle, 30089
Arneb, 25985,
Regulus, 49669
Babcock's star, 112247
Rigel, 24436
Barnard's,star, 87937
Rigil Kent, 71683
Bellatrix, 25336
Sadalmelik, 109074
Betelgeuse, 27989
Saiph, 27366
Campbell's star, 96295
Scheat, 113881
Canopus, 30438
Shaula, 85927
Capella, 24608
Shedir, 3179
Caph, 746
Sheliak, 92420
Castor, 36850
Sirius, 32349
Cor Caroli, 63125
Spica, 65474
Cyg X-1, 98298
Tarazed, 97278
Deneb, 102098
Thuban, 68756
Denebola, 57632
Unukalhai, 77070
Diphda, 3419
Van,Maanen 2, 3829
Dubhe, 54061
Vega, 91262
Enif, 107315
Vindemiatrix, 63608
Etamin, 87833
Zaurak, 18543
Fomalhaut, 113368
3C 273, 60936

337
plugins/planetarium/lj3.py Normal file
View file

@ -0,0 +1,337 @@
# 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.
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()
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 Config(redisIP,client):
global ClientNumber
r = redis.StrictRedis(host=redisIP, port=6379, db=0)
ClientNumber = client
osc_udp_client(redisIP, 8002, "LJ 8002")
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)

693
plugins/planetarium/main.py Executable file
View file

@ -0,0 +1,693 @@
#!/usr/bin/python3
# coding=UTF-8
'''
Multi Laser planetarium in python3 for LJ.
v0.01
Sam Neurohack
Accuracy could be tested against apparent data and starchart at https://www.calsky.com/cs.cgi?cha=7&sec=3&sub=2
Remember to set the same observer position and time.
See Readme for more information
Todo:
- use debug mode and check altaz calculated values against online sites.
- Validate aa2radec() with online calculator. Rewrite it to remove need for Astropy.
- Findout how to use OSC in python 3.
-
- Code WebUI page.
- UpdateStars() in each laser sky. Get magnitude. See UpdateSolar for example.
- All Draw operations should also check visibility in the given laser altitude range.
- Rewrite CityPosition() with proper search in a python dictionnary.
- Better python code. Better varuable to understand easily Update() methods.
LICENCE : CC
Remember : LJ will automatically warp geometry according to alignement data. See webUI.
'''
import redis
import lj3
import numpy as np
import math,time
from astropy.coordinates import SkyCoord, EarthLocation, AltAz
from astropy import units as u
from astropy.time import Time
from skyfield.api import Star, load, Topos,Angle
from skyfield.data import hipparcos
from osc4py3.as_eventloop import *
from osc4py3 import oscbuildparse
#from osc4py3 import oscmethod as osm
from osc4py3.oscmethod import *
import json
'''
is_py2 = sys.version[0] == '2'
if is_py2:
from Queue import Queue
else:
from queue import Queue
'''
#
# Arguments handler
#
import argparse
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Planetarium 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","--Lasers",help="Number of lasers connected (1 by default).",type=int)
argsparser.add_argument("-v","--verbose",help="Verbosity level (0 by default)",type=int)
argsparser.add_argument("-i","--input",help="inputs OSC Port (8005 by default)",type=int)
#argsparser.add_argument("-n","--name",help="City Name of the observer",type=str)
#argsparser.add_argument("-r","--redisIP",help="Country code of the observer ",type=str)
args = argsparser.parse_args()
if args.client:
ljclient = args.client
else:
ljclient = 0
if args.Lasers:
lasernumber = args.Lasers
else:
lasernumber = 1
if args.verbose:
debug = args.verbose
else:
debug = 0
if args.input:
OSCinPort = args.input
else:
OSCinPort = 8005
# Redis Computer IP
if args.redisIP != None:
redisIP = args.redisIP
else:
redisIP = '127.0.0.1'
lj3.Config(redisIP,ljclient)
#
# Inits Laser
#
fov = 256
viewer_distance = 2.2
width = 750
height = 750
centerX = width / 2
centerY = height / 2
samparray = [0] * 100
# If you want to use rgb for color :
def rgb2int(r,g,b):
return int('0x%02x%02x%02x' % (r,g,b),0)
white = rgb2int(255,255,255)
red = rgb2int(255,0,0)
blue = rgb2int(0,0,255)
green = rgb2int(0,255,0)
def Proj(x,y,z,angleX,angleY,angleZ):
rad = angleX * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
y2 = y
y = y2 * cosa - z * sina
z = y2 * sina + z * cosa
rad = angleY * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
z2 = z
z = z2 * cosa - x * sina
x = z2 * sina + x * cosa
rad = angleZ * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
x2 = x
x = x2 * cosa - y * sina
y = x2 * sina + y * cosa
""" Transforms this 3D point to 2D using a perspective projection. """
factor = fov / (viewer_distance + z)
x = x * factor + centerX
y = - y * factor + centerY
return (x,y)
#
# All the coordinates base functions
#
'''
To minize number of sky objects coordinates conversion : Change planetarium FOV in Ra Dec to select objects
(planets, hipparcos,..). Then get only those objects in AltAz coordinates.
aa2radec use Astropy to compute Equatorial Right Ascension and Declinaison coordinates from given observator Altitude and Azimuth.
Example ra,dec = aa2radec( azimuth = 0, altitude = 90, lati = 48.85341, longi = 2.3488, elevation = 100, t =AstroPyNow )
with AstroPyNow = Time.now()
'''
def aa2radec(azimuth, altitude, t):
#AstrObserver = EarthLocation(lat=lati * u.deg, lon=longi *u.deg, height= elevation*u.m,)
ObjectCoord = SkyCoord(alt = altitude * u.deg, az = azimuth *u.deg, obstime = t, frame = 'altaz', location = AstrObserver)
#print("icrs",ObjectCoord.icrs)
#print("ICRS Right Ascension", ObjectCoord.icrs.ra)
#print("ICRS Declination", ObjectCoord.icrs.dec)
return ObjectCoord.icrs.ra.degree, ObjectCoord.icrs.dec.degree
# Use Skyfield to compute given object apparent positions (ra,dec,alt,az) and distance from given gps earth position (in decimal degrees) at UTC time (in skyfield format)
def EarthObjPosition(object, t):
#print (object, 'at', t.utc_iso())
#SkyObserver = earth + Topos(gpslat, gpslong)
astrometric = earth.at(t).observe(object)
ra, dec, distance = astrometric.radec()
'''
print("Right ascencion",ra)
print("RA in degree",ra._degrees)
print("RA in radians",ra.radians)
print("declinaison",dec)
print (distance)
'''
ApparentPosition = SkyObserver.at(t).observe(object).apparent()
#alt, az, distance = ApparentPosition.altaz('standard')
alt, az, distance = ApparentPosition.altaz()
'''
print("UTC",t.utc_iso())
print ("Altitude",alt)
print("Altitude in radians",alt.radians)
print("Altitude in degrees",alt.degrees)
print("Altitude in dms",alt.dms(0))
print("Altitude in signed_dms",alt.signed_dms(0))
print("Azimuth", az.dstr())
print ("Distance from position", distance)
'''
# If you want degree hours min : print (object,alt,az)
# or you can do return ra._degrees, dec, alt.degrees, az, distance
return alt.degrees, az.degrees, distance
# Add Radec coordinates for all lasers from user defined Altaz coordinates in LaserSkies variable at given earth position and time.
# LaserSkies : [LeftAzi, RightAzi, TopAlt, BotAlt, LeftRa, RightRa, TopDec, BottomDec]
# 0 1 2 3 4 5 6 7
def RadecSkies(LaserSkies, AstroSkyTime):
print()
print("Converting", lasernumber, "LaserSkies limits in Right Ascension & Declination (radec) coordinates ")
for laser in range(lasernumber):
if debug > 0:
print("Laser",laser)
# Left top point
LaserSkies[laser][4],LaserSkies[laser][6] = aa2radec(azimuth = LaserSkies[laser][0], altitude =LaserSkies[laser][2], t =AstroSkyTime)
if debug > 0:
print(LaserSkies[laser][4],LaserSkies[laser][6])
# Right Bottom point
LaserSkies[laser][5],LaserSkies[laser][7] = aa2radec(azimuth = LaserSkies[laser][1], altitude =LaserSkies[laser][3], t =AstroSkyTime)
if debug > 0:
print(LaserSkies[laser][5],LaserSkies[laser][7])
if debug > 0:
print(LaserSkies)
print ("Done.")
def azimuth2scrX(leftAzi,rightAzi,s):
a1, a2 = leftAzi, rightAzi
b1, b2 = 0, width
#if debug > 0:
# print(leftAzi, rightAzi, s, b1 + ((s - a1) * (b2 - b1) / (a2 - a1)))
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
def altitude2scrY(topAlti,botAlti,s):
a1, a2 = topAlti, botAlti
b1, b2 = 0, height
#if debug > 0:
# print(topAlti,botAlti,s, b1 + ((s - a1) * (b2 - b1) / (a2 - a1)))
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
#
# Solar System
#
SolarObjectShape = [(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)]
# Planets Radius in km
SolarObjectradius = [
('Sun', 695500.0),
('Mercury', 2440.0),
('Venus', 6051.8),
('Earth', 6371.01),
('Mars', 3389.9),
('Jupiter', 69911.0),
('Saturn', 58232.0),
('Uranus', 25362.0),
('Neptune', 24624.0),
('134340 Pluto', 1195.0),
]
def LoadSolar():
global planets, SolarObjects, earth
print("Loading Solar System (de421)...")
# de421.bps https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/a_old_versions/de421.bsp
planets = load('data/de421.bsp')
earth = planets['earth']
print('Loaded.')
# de421 objects
# [Object name, object altitude, object azimuth]
SolarObjects = [['MERCURY',0.0, 0.0], ['VENUS', 0.0, 0.0], ['JUPITER BARYCENTER', 0.0, 0.0], ['SATURN BARYCENTER', 0.0, 0.0], ['URANUS BARYCENTER', 0.0, 0.0], ['NEPTUNE BARYCENTER', 0.0, 0.0], ['PLUTO BARYCENTER', 0.0, 0.0], ['SUN', 0.0, 0.0], ['MOON', 0.0, 0.0], ['MARS', 0.0, 0.0]]
def UpdateSolar():
global SolarObjects
# Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver.
for number,object in enumerate(SolarObjects):
#print(object[0],number)
SolarObjects[number][1], SolarObjects[number][2], distance = EarthObjPosition(planets[object[0]],SkyfieldTime)
if debug > 0:
PrintSolar()
def PrintSolar():
for number,object in enumerate(SolarObjects):
print (SolarObjects[number][0],"is at (alt,az)",SolarObjects[number][1],SolarObjects[number][2])
# Draw the SolarShapeObject for any Solar object is in the laser Sky
def DrawSolar(laser):
for number,object in enumerate(SolarObjects):
# Solar object is in given laser sky azimuth and altitude range ?
if LaserSkies[laser][0] < SolarObjects[number][2] < LaserSkies[laser][1] and LaserSkies[laser][3] < SolarObjects[number][1] < LaserSkies[laser][2]:
#print ("drawing",SolarObjects[number][0],SolarObjects[number][1],SolarObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(SolarObjectShape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],SolarObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],SolarObjects[number][1]), resize = 2, rotx =0, roty =0 , rotz=0)
#
# Stars
#
StarsObjectShape = [(-10,10), (-10,-10), (10,-10), (10,10), (-10,10)]
def LoadHipparcos(ts):
global hipdata
print("Loading hipparcos catalog...")
#hipparcosURL = 'ftp://cdsarc.u-strasbg.fr/cats/I/239/hip_main.dat.gz'
hipparcosURL = 'data/hip_main.dat.gz'
with load.open(hipparcosURL) as f:
hipdata = hipparcos.load_dataframe(f)
#print("Loaded.")
hipparcos_epoch = ts.tt(1991.25)
# CODE IMPORTED HERE FROM TESTS. NEEDS TO ADAPT
# Star selection
def StarSelect():
global StarsObjects, hipdatafilt
StarsObjects = [[]]
#hipparcos_epoch = ts.tt(1991.25)
#barnards_star = Star.from_dataframe(hipdata.loc[87937])
#polaris = Star.from_dataframe(hipdata.loc[11767])
print()
print ("Stars selection...")
hipdatafilt = hipdata[hipdata['magnitude'] <= 3.5]
print(('{} stars with magnitude <= 3.5'.format(len(hipdatafilt))))
Starnames = hipdatafilt.index
StarsObjects[0] = [Starnames[0],0,0]
for index in range(len(Starnames)-1):
StarsObjects.append([Starnames[index+1],0,0])
def UpdateStars(ts):
global StarsObjects
hipparcos_epoch = ts.tt(1991.25)
# Compute Alt Az coordinates for all solar objects for obsehttps://www.startpage.com/do/searchrver.
for number,object in enumerate(StarsObjects):
#print(object[0],number)
StarsObjects[number][1], StarsObjects[number][2], distance = EarthObjPosition(Star.from_dataframe(hipdatafilt.loc[StarsObjects[number][0]]),SkyfieldTime)
if debug > 0:
PrintStars()
def PrintStars():
for number,object in enumerate(StarsObjects):
print (StarsObjects[number][0],"is at (alt,az)",StarsObjects[number][1],StarsObjects[number][2])
def DrawStars(laser):
for number,object in enumerate(StarsObjects):
# Star object is in given lasersky altitude range ?
if LaserSkies[laser][3] < StarsObjects[number][1] < LaserSkies[laser][2]:
# Star object is in given lasersky azimuth range ?
if LaserSkies[laser][0] < StarsObjects[number][2] < LaserSkies[laser][1] :
#print ("drawing",StarsObjects[number][0],StarsObjects[number][1],StarsObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(StarsObjectShape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],StarsObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],StarsObjects[number][1]), resize = 0.05, rotx =0, roty =0 , rotz=0)
# Star object is in given lasersky North azimuth ?
if LaserSkies[laser][0] > LaserSkies[laser][1] and StarsObjects[number][2] < LaserSkies[laser][1] :
#print ("drawing",StarsObjects[number][0],StarsObjects[number][1],StarsObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(StarsObjectShape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],StarsObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],StarsObjects[number][1]), resize = 0.05, rotx =0, roty =0 , rotz=0)
#
# Anything system. Say you want
#
AnythingObjectShape = [(-50,30), (-30,-30), (30,-30), (10,30), (-50,30)]
def LoadAnything():
global planets, AnythingObjects, earth
print("Loading Anything System...")
# de421.bps https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/a_old_versions/de421.bsp
# planets = load('data/de421.bsp')
earth = planets['earth']
print('Loaded.')
# [Object name, object altitude, object azimuth]
AnythingObjects = [['MERCURY',0.0, 0.0], ['VENUS', 0.0, 0.0], ['JUPITER BARYCENTER', 0.0, 0.0], ['SATURN BARYCENTER', 0.0, 0.0], ['URANUS BARYCENTER', 0.0, 0.0], ['NEPTUNE BARYCENTER', 0.0, 0.0], ['PLUTO BARYCENTER', 0.0, 0.0], ['SUN', 0.0, 0.0], ['MOON', 0.0, 0.0], ['MARS', 0.0, 0.0]]
def UpdateAnything():
global AnythingObjects
# Compute Alt Az coordinates for all Anything objects for obsehttps://www.startpage.com/do/searchrver.
for number,object in enumerate(AnythingObjects):
#print(object[0],number)
AnythingObjects[number][1], AnythingObjects[number][2], distance = EarthObjPosition(planets[object[0]],SkyfieldTime)
if debug > 0:
PrintAnything()
def PrintAnything():
for number,object in enumerate(AnythingObjects):
print (AnythingObjects[number][0],"is at (alt,az)",AnythingObjects[number][1],AnythingObjects[number][2])
# Draw the AnythingShapeObject for any Anything object is in the laser Sky
def DrawAnything(laser):
for number,object in enumerate(AnythingObjects):
# Anything object is in given laser sky azimuth and altitude range ?
if LaserSkies[laser][0] < AnythingObjects[number][2] < LaserSkies[laser][1] and LaserSkies[laser][3] < AnythingObjects[number][1] < LaserSkies[laser][2]:
#print ("drawing",AnythingObjects[number][0],AnythingObjects[number][1],AnythingObjects[number][2],"on laser",laser)
lj3.rPolyLineOneColor(AnythingObjectShape, c = white, PL = laser, closed = False, xpos = azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],AnythingObjects[number][2]), ypos = altitude2scrY(LaserSkies[laser][2],LaserSkies[laser][3],AnythingObjects[number][1]), resize = 2, rotx =0, roty =0 , rotz=0)
#
# On Earth Gps positions
# from https://github.com/lutangar/cities.json
#
def LoadCities():
global world
print("Loading World Cities GPS position...")
f=open("data/cities.json","r")
s = f.read()
world = json.loads(s)
#print("Loaded.")
# Get longitude and latitude of given City in given country. Need to better understand python dictionnaries.
def CityPositiion(cityname, countrycode):
for city in range(len(world['cities'])):
if world['cities'][city]['name']==cityname and world['cities'][city]['country']==countrycode:
'''
print (world['cities'][city]['country'])
print (world['cities'][city]['name'])
print (world['cities'][city]['lat'])
print (world['cities'][city]['lng'])
'''
return float(world['cities'][city]['lat']), float(world['cities'][city]['lng'])
# Add Kompass orientation to given laser point list if it is in laser sky at Y axis 300
# point lasers to
def DrawOrientation(laser):
#print("LaserSkies 0",LaserSkies[laser][0],"LaserSkies 1",LaserSkies[laser][1])
# North direction is in given laser sky azimuth range?
if LaserSkies[laser][1] < LaserSkies[laser][0]:
#print ("N az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("NORTH",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],359), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
# East direction is in given laser sky azimuth range ?
if LaserSkies[laser][0] <= 90 < LaserSkies[laser][1]:
#print ("E az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("EAST",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],90), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
# South direction is in given laser sky azimuth range ?
if LaserSkies[laser][0] <= 180 < LaserSkies[laser][1]:
#print ("S az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("SOUTH",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],180), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
# West direction is in given laser sky azimuth range ?
if LaserSkies[laser][0] <= 270 < LaserSkies[laser][1]:
#print ("W az",azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],0))
lj3.Text("WEST",white,laser,azimuth2scrX(LaserSkies[laser][0],LaserSkies[laser][1],270), 770, resize = 0.5, rotx =0, roty =0 , rotz=0)
# Compute LaserSkies Coordinates for observer
def InitObserver(SkyCity, SkyCountryCode, time,ts):
global LaserSkies, Skylat, Skylong, SkyfieldTime, AstrObserver, SkyObserver
# Observer position i.e : Paris FR
#Skylat = 48.85341 # decimal degree
#Skylong = 2.3488 # decimal degree
#print()
print("Observer GPS position and time...")
Skylat, Skylong = CityPositiion(SkyCity,SkyCountryCode)
print ("GPS Position of",SkyCity, "in", SkyCountryCode, ":",Skylat,Skylong)
# City GPS altitude not in Cities database... Let's say it's :
Skyelevation = 0 # meters
# Observer Time : Now
# Other time in Astropy style
# times = '1999-01-01T00:00:00.123456789'
# t = Time(times, format='isot', scale='utc')
#print()
AstroSkyTime = time
print ("AstroPy time", AstroSkyTime)
SkyfieldTime = ts.from_astropy(AstroSkyTime)
print("SkyfieldTime from AstropyUTC",SkyfieldTime.utc_iso())
AstrObserver = EarthLocation(lat = Skylat * u.deg, lon = Skylong * u.deg, height = Skyelevation * u.m,)
SkyObserver = earth + Topos(Skylat, Skylong)
# Computer for all Laser "skies" their Right Ascension/Declinaison coordinates from their Altitude/azimuth Coordinates.
# to later select their visible objects in radec catalogs like hipparcos.
# LaserSky definition for one laser (in decimal degrees) : [RightAzi, LeftAzi, TopAlt, BotAlt, LeftRa, RightRa, TopDec, BottomDec]
# With 4 lasers with each one a quarter of the 360 ° real sky, there is 4 LaserSky :
LaserSkies = [[45,135.0,90.0,0.0,0.0,0.0,0.0,0.0],[135,225,90,0,0,0,0,0],[225,315,90,0,0,0,0,0],[305,0,90,0,0,0,0,0]]
RadecSkies(LaserSkies, AstroSkyTime)
# Change Observer position by adding deltas (Gpslong, gpslat, elevation in decimal degree/meters)
def UpdateObserver(gpslatdelta, gpslongdelta, elevationdelta,time,ts):
global LaserSkies, Skylat, Skylong, SkyfieldTime, AstrObserver, SkyObserver
Skylat += gpslatdelta
Skylong += gpslongdelta
Skyelevation += elevationdelta
AstroSkyTime = time
print ("AstroPy time", AstroSkyTime)
SkyfieldTime = ts.from_astropy(AstroSkyTime)
print("SkyfieldTime from AstropyUTC",SkyfieldTime.utc_iso())
AstrObserver = EarthLocation(lat = Skylat * u.deg, lon = Skylong * u.deg, height = Skyelevation * u.m,)
SkyObserver = earth + Topos(Skylat, Skylong)
RadecSkies(LaserSkies, AstroSkyTime)
UpdateSolar()
UpdateStars()
UpdateAnything()
def NewTime(timeshift):
SkyfieldTime += timeshift
if DisplaySolar:
UpdateSolar()
if DisplayStars:
UpdateStars()
if DisplayAnything:
UpdateAnything()
def OSCstart(value):
# Will receive message address, and message data flattened in s, x, y
print("Planetarium OSC server got /planet/start with value", value)
def OSCUI(value):
# Will receive message address, and message data flattened in s, x, y
print("Planetarium OSC server got /planet/planetUI with value", value)
def WebStatus(message):
lj3.Send("/status",message)
#
# Main part
#
try:
WebStatus("Planetarium")
# 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("/planet/start*", OSCstart)
osc_method("/planet/planetUI*", OSCUI)
WebStatus("Load Cities.")
ts = load.timescale()
LoadCities()
SkyCity = 'Paris'
SkyCountryCode = 'FR'
WebStatus(SkyCity)
WebStatus("Solar System..")
LoadSolar()
WebStatus("Observer..")
InitObserver(SkyCity, SkyCountryCode, Time.now(),ts)
WebStatus("Load Stars..")
LoadHipparcos(ts)
StarSelect()
WebStatus("Updating...")
print("Updating solar system (de421) objects position for observer at", Skylat, Skylong, "time", SkyfieldTime.utc_iso())
UpdateSolar()
print("Updating stars for observer at", Skylat, Skylong, "time", SkyfieldTime.utc_iso())
UpdateStars(ts)
WebStatus("Ready")
lj3.Send("/planet/start",1)
print ("Done.")
# UpdateStars() Todo
DisplayStars = True
DisplaySolar = False
DisplayOrientation = True
DisplayAnything = False
print("Start displaying on",lasernumber,"lasers")
while 1:
for laser in range(lasernumber):
#print ("Drawing laser",lasernumber)
if DisplayOrientation:
DrawOrientation(laser)
lj3.OSCframe()
if DisplaySolar:
DrawSolar(laser)
lj3.OSCframe()
if DisplayStars:
DrawStars(laser)
lj3.OSCframe()
if DisplayAnything:
DrawAnything()
lj3.OSCframe()
lj3.DrawPL(laser)
lj3.OSCframe()
time.sleep(0.01)
except KeyboardInterrupt:
pass
# Gently stop on CTRL C
finally:
WebStatus("Planet Exit")
print("Stopping OSC...")
lj3.OSCstop()
print ("Fin du planetarium.")

245
plugins/simu.py Executable file
View file

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

130
plugins/textcycl.py Normal file
View file

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