forked from protonphoton/LJ
Better redis doc
This commit is contained in:
parent
56e95c4c4b
commit
c5c7051ddc
16
README.md
16
README.md
@ -172,18 +172,18 @@ A "plugin" is a software that send any number of pointlist(s). LJ comes with dif
|
|||||||
# Client Side : Program your own "plugin"
|
# Client Side : Program your own "plugin"
|
||||||
#
|
#
|
||||||
|
|
||||||
The server approach is based on redis, so you can write and run your laser client software in any redis capable programming langage (50+ : https://redis.io/clients). An external program that just send pointlists is a "client". If you want some interactions from the webUI, like text status area support, crash detection, launch,... it's a "plugin" and some default code is needed. See custom1.py, a basic plugin you can modiffy. LJ and plugins signaling is mainly over OSC.
|
The server approach is based on redis, so you can write and run your laser client software in any redis capable programming langage (50+ : https://redis.io/clients). An external program that just send pointlists to redis is a "client". If you want some interactions from the webUI, like text status area support, crash detection, autostart,... it's a "plugin" and some default code is needed. LJ and plugins signaling is over OSC.
|
||||||
|
|
||||||
- Read all this readme ;-)
|
- Read all this readme ;-)
|
||||||
- Generate at least one pointlist array (say a square) with *enough points*, one point is likely to fail for buffering reason. See command reference below for more.
|
- Generate at least one pointlist array (say a square) with *enough points*, one point is likely to fail for buffering reason.
|
||||||
- Feed your point list array in string format to redis server. i.e use "/pl/0/1" redis key to feed scene 0, laser 1.
|
- Feed your point list array in string format to redis server. i.e use "/pl/0/1" redis key to feed scene 0, laser 1. See /pl/ command in command reference below how to send your pointlist to i.e /pl/0/1 redis key.
|
||||||
- Tell LJ.conf your plugin configuration : OSC port and command line to start it.
|
- Tell LJ.conf your plugin configuration : OSC port and command line to start it.
|
||||||
- At least a plugin must reply /pong to OSC request /ping.
|
- At least a plugin must reply /pong to OSC request /ping.
|
||||||
|
|
||||||
Currently the WebUI (www/index.html) is static.
|
Currently the WebUI (www/index.html) is static.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Client side dope mode : How to use lj23 (python3)
|
# Client side dope mode for python 3 generators : How to use lj23
|
||||||
#
|
#
|
||||||
|
|
||||||
lj23 have many very useful functions to not reinvent the wheel for advanced points generation "client" side : layers, sprites, built in rotations,..
|
lj23 have many very useful functions to not reinvent the wheel for advanced points generation "client" side : layers, sprites, built in rotations,..
|
||||||
@ -191,7 +191,7 @@ lj23 have many very useful functions to not reinvent the wheel for advanced poin
|
|||||||
|
|
||||||
4 Great TRICKS with lj23 :
|
4 Great TRICKS with lj23 :
|
||||||
|
|
||||||
First open square.py and learn how to declare different objects. square.py is a 2D shape example in 3D rotation (red/green anaglyph rendering) that use 2 layers : one for left eye and one for right eye.
|
First open custom1.py and learn how to declare different objects. custom1.py is a 2D shape example in 3D rotation (red/green anaglyph rendering) that use 2 layers : one for left eye and one for right eye. custom1 is a copy of square.py
|
||||||
|
|
||||||
|
|
||||||
1/ How to have another laser drawing the same thing ?
|
1/ How to have another laser drawing the same thing ?
|
||||||
@ -370,12 +370,16 @@ Generic :
|
|||||||
# LJ commands reference
|
# LJ commands reference
|
||||||
#
|
#
|
||||||
|
|
||||||
All commands are available via OSC (port 8002) or websocket (port 9001)
|
All these commands are available via OSC (port 8002) or websocket (port 9001)
|
||||||
|
|
||||||
|
|
||||||
/pl/scenenumber/lasernumber value : value is the pointlist to draw as string. Example :
|
/pl/scenenumber/lasernumber value : value is the pointlist to draw as string. Example :
|
||||||
/pl/0/0 "[(150.0, 230.0, 65280), (170.0, 170.0, 65280), (230.0, 170.0, 65280), (210.0, 230.0, 65280), (150.0, 230.0, 65280)]"
|
/pl/0/0 "[(150.0, 230.0, 65280), (170.0, 170.0, 65280), (230.0, 170.0, 65280), (210.0, 230.0, 65280), (150.0, 230.0, 65280)]"
|
||||||
|
|
||||||
|
Use the same syntax if you send your pointlist directly in redis : "/pl/0/0" is the key and value is "[(150.0,..."
|
||||||
|
|
||||||
|
Every point must be : (x,y,color). Color is the hex color #FFFFFF in decimal.
|
||||||
|
|
||||||
|
|
||||||
/scale/X/lasernumber value
|
/scale/X/lasernumber value
|
||||||
|
|
||||||
|
277
plugins/custom1.py
Normal file
277
plugins/custom1.py
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# -*- mode: Python -*-
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
custom1
|
||||||
|
v0.1.0
|
||||||
|
|
||||||
|
A copy of square.py you can modify to code your plugin.
|
||||||
|
custom1 has necessary hooks in LJ.conf, webui and so on.
|
||||||
|
|
||||||
|
|
||||||
|
LICENCE : CC
|
||||||
|
|
||||||
|
by Sam Neurohack
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
print()
|
||||||
|
ljpath = r'%s' % os.getcwd().replace('\\','/')
|
||||||
|
|
||||||
|
# import from shell
|
||||||
|
|
||||||
|
sys.path.append(ljpath +'/../libs/')
|
||||||
|
|
||||||
|
#import from LJ
|
||||||
|
sys.path.append(ljpath +'/libs/')
|
||||||
|
print(ljpath+'/../libs/')
|
||||||
|
|
||||||
|
import lj23layers as lj
|
||||||
|
|
||||||
|
sys.path.append('../libs')
|
||||||
|
from OSC3 import OSCServer, OSCClient, OSCMessage
|
||||||
|
import redis
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
OSCinPort = 8014
|
||||||
|
|
||||||
|
print ("")
|
||||||
|
print ("Arguments parsing if needed...")
|
||||||
|
argsparser = argparse.ArgumentParser(description="Custom1 example 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("-s","--scene",help="LJ scene 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)
|
||||||
|
argsparser.add_argument("-m","--myIP",help="Local IP (127.0.0.1 by default) ",type=str)
|
||||||
|
|
||||||
|
args = argsparser.parse_args()
|
||||||
|
|
||||||
|
if args.scene:
|
||||||
|
ljscene = args.scene
|
||||||
|
else:
|
||||||
|
ljscene = 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'
|
||||||
|
|
||||||
|
print("redisIP",redisIP)
|
||||||
|
|
||||||
|
# myIP
|
||||||
|
if args.myIP != None:
|
||||||
|
myIP = args.myIP
|
||||||
|
else:
|
||||||
|
myIP = '127.0.0.1'
|
||||||
|
|
||||||
|
print("myIP",myIP)
|
||||||
|
if args.verbose:
|
||||||
|
debug = args.verbose
|
||||||
|
else:
|
||||||
|
debug = 0
|
||||||
|
|
||||||
|
# Useful variables init.
|
||||||
|
white = lj.rgb2int(255,255,255)
|
||||||
|
red = lj.rgb2int(255,0,0)
|
||||||
|
blue = lj.rgb2int(0,0,255)
|
||||||
|
green = lj.rgb2int(0,255,0)
|
||||||
|
|
||||||
|
width = 800
|
||||||
|
height = 600
|
||||||
|
centerX = width / 2
|
||||||
|
centerY = height / 2
|
||||||
|
|
||||||
|
# 3D to 2D projection parameters
|
||||||
|
fov = 256
|
||||||
|
viewer_distance = 2.2
|
||||||
|
|
||||||
|
# Anaglyph computation parameters for right and left eyes.
|
||||||
|
# algorythm come from anaglyph geo maps
|
||||||
|
eye_spacing = 100
|
||||||
|
nadir = 0.5
|
||||||
|
observer_altitude = 30000
|
||||||
|
map_layerane_altitude = 0.0
|
||||||
|
|
||||||
|
# square coordinates : vertices that compose each of the square.
|
||||||
|
vertices = [
|
||||||
|
(- 1.0, 1.0,- 1.0),
|
||||||
|
( 1.0, 1.0,- 1.0),
|
||||||
|
( 1.0,- 1.0,- 1.0),
|
||||||
|
(- 1.0,- 1.0,- 1.0)
|
||||||
|
]
|
||||||
|
|
||||||
|
face = [0,1,2,3]
|
||||||
|
|
||||||
|
#
|
||||||
|
# LJ inits
|
||||||
|
#
|
||||||
|
|
||||||
|
layer = 0
|
||||||
|
|
||||||
|
# Setup LJ library mandatory properties for this plugin
|
||||||
|
lj.Config(redisIP, ljscene, "custom1")
|
||||||
|
|
||||||
|
# Define properties for each drawn "element" : name, intensity, active, xy, color, red, green, blue, layer , closed
|
||||||
|
Leftsquare = lj.FixedObject('Leftsquare', True, 255, [], red, 255, 0, 0, layer , True)
|
||||||
|
Rightsquare = lj.FixedObject('Rightsquare', True, 255, [], green, 0, 255, 0, layer , True)
|
||||||
|
|
||||||
|
# 'Destination' for given layer : name, number, active, layer , scene, laser
|
||||||
|
Dest0 = lj.DestObject('0', 0, True, 0 , 0, 0) # Dest0 will send layer 0 points to scene 0, laser 0
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Anaglyph computation : different X coordinate for each eye
|
||||||
|
#
|
||||||
|
|
||||||
|
def LeftShift(elevation):
|
||||||
|
|
||||||
|
diff = elevation - map_layerane_altitude
|
||||||
|
return nadir * eye_spacing * diff / (observer_altitude - elevation)
|
||||||
|
|
||||||
|
def RightShift(elevation):
|
||||||
|
|
||||||
|
diff = map_layerane_altitude - elevation
|
||||||
|
return (1 - nadir) * eye_spacing * diff / (observer_altitude - elevation)
|
||||||
|
|
||||||
|
#
|
||||||
|
# OSC
|
||||||
|
#
|
||||||
|
|
||||||
|
oscserver = OSCServer( (myIP, OSCinPort) )
|
||||||
|
oscserver.timeout = 0
|
||||||
|
|
||||||
|
|
||||||
|
# this method of reporting timeouts only works by convention
|
||||||
|
# that before calling handle_request() field .timed_out is
|
||||||
|
# set to False
|
||||||
|
def handle_timeout(self):
|
||||||
|
self.timed_out = True
|
||||||
|
|
||||||
|
# funny python's way to add a method to an instance of a class
|
||||||
|
import types
|
||||||
|
oscserver.handle_timeout = types.MethodType(handle_timeout, oscserver)
|
||||||
|
|
||||||
|
|
||||||
|
# OSC callbacks
|
||||||
|
|
||||||
|
# /custom1/ljscene
|
||||||
|
def OSCljscene(path, tags, args, source):
|
||||||
|
|
||||||
|
print("Got /custom1/ljscene with value", args[0])
|
||||||
|
lj.WebStatus("custom1 to virtual "+ str(args[0]))
|
||||||
|
ljscene = args[0]
|
||||||
|
lj.Ljscene(ljscene)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main
|
||||||
|
#
|
||||||
|
|
||||||
|
def Run():
|
||||||
|
|
||||||
|
|
||||||
|
Left = []
|
||||||
|
Right = []
|
||||||
|
counter =0
|
||||||
|
#lj.SendLJ("/custom1/start 1")
|
||||||
|
|
||||||
|
# OSC Server callbacks
|
||||||
|
print("Starting OSC server at",myIP," port",OSCinPort,"...")
|
||||||
|
oscserver.addMsgHandler( "/custom1/ljscene", OSCljscene )
|
||||||
|
|
||||||
|
# Add OSC generic plugins commands : 'default", /ping, /quit, /pluginame/obj, /pluginame/var, /pluginame/adddest, /pluginame/deldest
|
||||||
|
lj.addOSCdefaults(oscserver)
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
while lj.oscrun:
|
||||||
|
|
||||||
|
lj.OSCframe()
|
||||||
|
Left = []
|
||||||
|
Right = []
|
||||||
|
|
||||||
|
x = vertices[0][0]
|
||||||
|
y = vertices[0][1]
|
||||||
|
z = vertices[0][2]
|
||||||
|
|
||||||
|
# LJ tracers will "move" the laser to this first point in black, then move to the next with second point color.
|
||||||
|
# For more accuracy in dac emulator, repeat this first point.
|
||||||
|
|
||||||
|
# Generate all points in square.
|
||||||
|
for point in face:
|
||||||
|
x = vertices[point][0]
|
||||||
|
y = vertices[point][1]
|
||||||
|
z = vertices[point][2]
|
||||||
|
|
||||||
|
Left.append(Proj(x+LeftShift(z*25),y,z,0,counter,0))
|
||||||
|
Right.append(Proj(x+RightShift(z*25),y,z,0,counter,0))
|
||||||
|
|
||||||
|
|
||||||
|
lj.PolyLineOneColor(Left, c = Leftsquare.color , layer = Leftsquare.layer, closed = Leftsquare.closed)
|
||||||
|
lj.PolyLineOneColor(Right, c = Rightsquare.color , layer = Rightsquare.layer, closed = Rightsquare.closed)
|
||||||
|
|
||||||
|
lj.DrawDests()
|
||||||
|
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
counter += 1
|
||||||
|
if counter > 360:
|
||||||
|
counter = 0
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Gently stop on CTRL C
|
||||||
|
|
||||||
|
finally:
|
||||||
|
|
||||||
|
lj.ClosePlugin()
|
||||||
|
|
||||||
|
|
||||||
|
Run()
|
279
plugins/square.py
Normal file
279
plugins/square.py
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# -*- mode: Python -*-
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
Square
|
||||||
|
v0.1.0
|
||||||
|
|
||||||
|
Anaglyphed rotating square (for red and green glasses)
|
||||||
|
|
||||||
|
This scene uses the drawing functions provided by LJ in lj23.py
|
||||||
|
|
||||||
|
LICENCE : CC
|
||||||
|
|
||||||
|
by Sam Neurohack
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
print()
|
||||||
|
ljpath = r'%s' % os.getcwd().replace('\\','/')
|
||||||
|
|
||||||
|
# import from shell
|
||||||
|
|
||||||
|
sys.path.append(ljpath +'/../libs/')
|
||||||
|
|
||||||
|
#import from LJ
|
||||||
|
sys.path.append(ljpath +'/libs/')
|
||||||
|
print(ljpath+'/../libs/')
|
||||||
|
|
||||||
|
import lj23layers as lj
|
||||||
|
|
||||||
|
sys.path.append('../libs')
|
||||||
|
from OSC3 import OSCServer, OSCClient, OSCMessage
|
||||||
|
import redis
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
OSCinPort = 8013
|
||||||
|
|
||||||
|
print ("")
|
||||||
|
print ("Arguments parsing if needed...")
|
||||||
|
argsparser = argparse.ArgumentParser(description="Square example 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("-s","--scene",help="LJ scene 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)
|
||||||
|
argsparser.add_argument("-m","--myIP",help="Local IP (127.0.0.1 by default) ",type=str)
|
||||||
|
|
||||||
|
args = argsparser.parse_args()
|
||||||
|
|
||||||
|
if args.scene:
|
||||||
|
ljscene = args.scene
|
||||||
|
else:
|
||||||
|
ljscene = 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'
|
||||||
|
|
||||||
|
print("redisIP",redisIP)
|
||||||
|
|
||||||
|
# myIP
|
||||||
|
if args.myIP != None:
|
||||||
|
myIP = args.myIP
|
||||||
|
else:
|
||||||
|
myIP = '127.0.0.1'
|
||||||
|
|
||||||
|
print("myIP",myIP)
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
debug = args.verbose
|
||||||
|
else:
|
||||||
|
debug = 0
|
||||||
|
|
||||||
|
# Useful variables init.
|
||||||
|
white = lj.rgb2int(255,255,255)
|
||||||
|
red = lj.rgb2int(255,0,0)
|
||||||
|
blue = lj.rgb2int(0,0,255)
|
||||||
|
green = lj.rgb2int(0,255,0)
|
||||||
|
|
||||||
|
width = 800
|
||||||
|
height = 600
|
||||||
|
centerX = width / 2
|
||||||
|
centerY = height / 2
|
||||||
|
|
||||||
|
# 3D to 2D projection parameters
|
||||||
|
fov = 256
|
||||||
|
viewer_distance = 2.2
|
||||||
|
|
||||||
|
# Anaglyph computation parameters for right and left eyes.
|
||||||
|
# algorythm come from anaglyph geo maps
|
||||||
|
eye_spacing = 100
|
||||||
|
nadir = 0.5
|
||||||
|
observer_altitude = 30000
|
||||||
|
map_layerane_altitude = 0.0
|
||||||
|
|
||||||
|
# square coordinates : vertices that compose each of the square.
|
||||||
|
vertices = [
|
||||||
|
(- 1.0, 1.0,- 1.0),
|
||||||
|
( 1.0, 1.0,- 1.0),
|
||||||
|
( 1.0,- 1.0,- 1.0),
|
||||||
|
(- 1.0,- 1.0,- 1.0)
|
||||||
|
]
|
||||||
|
|
||||||
|
face = [0,1,2,3]
|
||||||
|
|
||||||
|
#
|
||||||
|
# LJ inits
|
||||||
|
#
|
||||||
|
|
||||||
|
layer = 0
|
||||||
|
|
||||||
|
# Setup LJ library mandatory properties.
|
||||||
|
lj.Config(redisIP, ljscene, "square")
|
||||||
|
|
||||||
|
# You can define properties for each drawn "element" : name, intensity, active, xy, color, red, green, blue, layer , closed
|
||||||
|
Leftsquare = lj.FixedObject('Leftsquare', True, 255, [], red, 255, 0, 0, layer , True)
|
||||||
|
Rightsquare = lj.FixedObject('Rightsquare', True, 255, [], blue, 0, 255, 0, layer , True)
|
||||||
|
|
||||||
|
# 'Destination' for given layer : name, number, active, layer , scene, laser
|
||||||
|
Dest0 = lj.DestObject('0', 0, True, 0 , 0, 0) # Dest0 will send layer 0 points to scene 0, laser 0
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Anaglyph computation : different X coordinate for each eye
|
||||||
|
#
|
||||||
|
|
||||||
|
def LeftShift(elevation):
|
||||||
|
|
||||||
|
diff = elevation - map_layerane_altitude
|
||||||
|
return nadir * eye_spacing * diff / (observer_altitude - elevation)
|
||||||
|
|
||||||
|
def RightShift(elevation):
|
||||||
|
|
||||||
|
diff = map_layerane_altitude - elevation
|
||||||
|
return (1 - nadir) * eye_spacing * diff / (observer_altitude - elevation)
|
||||||
|
|
||||||
|
#
|
||||||
|
# OSC
|
||||||
|
#
|
||||||
|
|
||||||
|
oscserver = OSCServer( (myIP, OSCinPort) )
|
||||||
|
oscserver.timeout = 0
|
||||||
|
|
||||||
|
|
||||||
|
# this method of reporting timeouts only works by convention
|
||||||
|
# that before calling handle_request() field .timed_out is
|
||||||
|
# set to False
|
||||||
|
def handle_timeout(self):
|
||||||
|
self.timed_out = True
|
||||||
|
|
||||||
|
# funny python's way to add a method to an instance of a class
|
||||||
|
import types
|
||||||
|
oscserver.handle_timeout = types.MethodType(handle_timeout, oscserver)
|
||||||
|
|
||||||
|
|
||||||
|
# OSC callbacks
|
||||||
|
|
||||||
|
# /square/ljscene
|
||||||
|
def OSCljscene(path, tags, args, source):
|
||||||
|
|
||||||
|
print("Got /square/ljscene with value", args[0])
|
||||||
|
lj.WebStatus("square to virtual "+ str(args[0]))
|
||||||
|
ljscene = args[0]
|
||||||
|
lj.Ljscene(ljscene)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main
|
||||||
|
#
|
||||||
|
|
||||||
|
def Run():
|
||||||
|
|
||||||
|
|
||||||
|
Left = []
|
||||||
|
Right = []
|
||||||
|
counter =0
|
||||||
|
lj.WebStatus("Square")
|
||||||
|
lj.SendLJ("/square/start 1")
|
||||||
|
|
||||||
|
# OSC Server callbacks
|
||||||
|
print("Starting OSC server at",myIP," port",OSCinPort,"...")
|
||||||
|
oscserver.addMsgHandler( "/square/ljscene", OSCljscene )
|
||||||
|
|
||||||
|
# Add OSC generic plugins commands : 'default", /ping, /quit, /pluginame/obj, /pluginame/var, /pluginame/adddest, /pluginame/deldest
|
||||||
|
lj.addOSCdefaults(oscserver)
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
while lj.oscrun:
|
||||||
|
|
||||||
|
lj.OSCframe()
|
||||||
|
Left = []
|
||||||
|
Right = []
|
||||||
|
|
||||||
|
x = vertices[0][0]
|
||||||
|
y = vertices[0][1]
|
||||||
|
z = vertices[0][2]
|
||||||
|
|
||||||
|
# LJ tracers will "move" the laser to this first point in black, then move to the next with second point color.
|
||||||
|
# For more accuracy in dac emulator, repeat this first point.
|
||||||
|
|
||||||
|
# Generate all points in square.
|
||||||
|
for point in face:
|
||||||
|
x = vertices[point][0]
|
||||||
|
y = vertices[point][1]
|
||||||
|
z = vertices[point][2]
|
||||||
|
|
||||||
|
Left.append(Proj(x+LeftShift(z*25),y,z,0,counter,0))
|
||||||
|
Right.append(Proj(x+RightShift(z*25),y,z,0,counter,0))
|
||||||
|
|
||||||
|
|
||||||
|
lj.PolyLineOneColor(Left, c = Leftsquare.color , layer = Leftsquare.layer, closed = Leftsquare.closed)
|
||||||
|
lj.PolyLineOneColor(Right, c = Rightsquare.color , layer = Rightsquare.layer, closed = Rightsquare.closed)
|
||||||
|
|
||||||
|
lj.DrawDests()
|
||||||
|
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
counter += 1
|
||||||
|
if counter > 360:
|
||||||
|
counter = 0
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Gently stop on CTRL C
|
||||||
|
|
||||||
|
finally:
|
||||||
|
|
||||||
|
lj.ClosePlugin()
|
||||||
|
|
||||||
|
|
||||||
|
Run()
|
Loading…
Reference in New Issue
Block a user