conf template and bugfixs

This commit is contained in:
sam 2020-09-29 22:40:10 +02:00
parent 93a5bf7fe5
commit 71bcd8ba68
17 changed files with 1433 additions and 74 deletions

47
LJ.conf
View File

@ -1,5 +1,5 @@
[General] [General]
lasernumber = 1 lasernumber = 4
debug = 0 debug = 0
ljayserverip = 0.0.0.0 ljayserverip = 0.0.0.0
wwwip = 192.168.2.43 wwwip = 192.168.2.43
@ -13,13 +13,13 @@ type = DS1000
ip = 192.168.2.4 ip = 192.168.2.4
kpps = 25000 kpps = 25000
centerx = 0 centerx = 0
centery = 0 centery = 765
zoomx = 45.0 zoomx = 45.0
zoomy = 45.0 zoomy = 45.0
sizex = 32000 sizex = 32000
sizey = 32000 sizey = 32000
finangle = 0.0 finangle = 0.0
swapx = 1 swapx = -1
swapy = -1 swapy = -1
lsteps = [ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] lsteps = [ (1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]
warpdest = [[-1500., 1500.], warpdest = [[-1500., 1500.],
@ -32,20 +32,20 @@ color = -1
type = LOCAL type = LOCAL
ip = 192.168.2.43 ip = 192.168.2.43
kpps = 25000 kpps = 25000
centerx = 0 centerx = -11970
centery = 0 centery = -6510
zoomx = 45.0 zoomx = 30.0
zoomy = 45.0 zoomy = 30.0
sizex = 32000 sizex = 32000
sizey = 32000 sizey = 32000
finangle = -30.0 finangle = 0.0
swapx = -1 swapx = -1
swapy = -1 swapy = -1
lsteps = [ (1.0, 2),(0.25, 1), (0.75, 1), (1.0, 5)] lsteps = [ (1.0, 2),(0.25, 1), (0.75, 1), (1.0, 5)]
warpdest = [[-1500., 1500.], warpdest = [[-1500., 1500.],
[ 1500., 1500.], [ 1500., 1500.],
[ 1500.,-1500.], [ 1500.,-1500.],
[-1500.,-1500.]] [-1500.,-1500.]]
[laser2] [laser2]
color = -1 color = -1
@ -63,14 +63,14 @@ swapx = -1
swapy = -1 swapy = -1
lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]
warpdest = [[-1500., 1500.], warpdest = [[-1500., 1500.],
[ 1500., 1500.], [ 1500., 1500.],
[ 1500.,-1500.], [ 1500.,-1500.],
[-1500.,-1500.]] [-1500.,-1500.]]
[laser3] [laser3]
color = -1 color = -1
type = LUKE400 type = LUKE400
ip = 192.168.1.5 ip = 192.168.2.3
kpps = 25000 kpps = 25000
centerx = 0 centerx = 0
centery = 0 centery = 0
@ -83,19 +83,13 @@ swapx = -1
swapy = -1 swapy = -1
lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)] lsteps = [(1.0, 8),(0.25, 3), (0.75, 3), (1.0, 10)]
warpdest = [[-1500., 1500.], warpdest = [[-1500., 1500.],
[ 1500., 1500.], [ 1500., 1500.],
[ 1500.,-1500.], [ 1500.,-1500.],
[-1500.,-1500.]] [-1500.,-1500.]]
[plugins] [plugins]
plugins = { plugins = {
"trckr": {"OSC": 8017, "command": "python3 plugins/VJing/trckr.py", "display": True},
"aurora": {"OSC": 8090, "command": "python3 plugins/aurora/aurora.py", "display": True}, "aurora": {"OSC": 8090, "command": "python3 plugins/aurora/aurora.py", "display": True},
"maxw": {"OSC": 8012, "command": "python3 plugins/maxwell.py", "display": True},
"square": {"OSC": 8013, "command": "python3 plugins/square.py", "display": True},
"custom1": {"OSC": 8014, "command": "python3 plugins/custom1.py", "display": True},
"mitraille": {"OSC": 8015, "command": "python3 plugins/audio/mitraille.py", "display": True},
"livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True},
"nozoid": {"OSC": 8003, "command": "python3 plugins/audio/nozoids3.py", "display": True}, "nozoid": {"OSC": 8003, "command": "python3 plugins/audio/nozoids3.py", "display": True},
"glyph": {"OSC": 8004, "command": "python3 plugins/laserglyph.py", "display": True}, "glyph": {"OSC": 8004, "command": "python3 plugins/laserglyph.py", "display": True},
"planet": {"OSC": 8005, "command": "python3 plugins/planetarium/main.py", "display": True}, "planet": {"OSC": 8005, "command": "python3 plugins/planetarium/main.py", "display": True},
@ -103,6 +97,11 @@ plugins = {
"cycl": {"OSC": 8007, "command": "python3 plugins/textcycl.py", "display": True}, "cycl": {"OSC": 8007, "command": "python3 plugins/textcycl.py", "display": True},
"simu": {"OSC": 8008, "command": "python plugins/pysimu.py", "display": False}, "simu": {"OSC": 8008, "command": "python plugins/pysimu.py", "display": False},
"artnet": {"OSC": 8009, "command": "python3 libs3/artnet.py", "display": False}, "artnet": {"OSC": 8009, "command": "python3 libs3/artnet.py", "display": False},
"trckr": {"OSC": 8017, "command": "python3 plugins/trckr.py", "display": False},
"maxw": {"OSC": 8012, "command": "python3 plugins/maxwell.py", "display": True},
"square": {"OSC": 8013, "command": "python3 plugins/square.py", "display": True},
"custom1": {"OSC": 8014, "command": "python3 plugins/custom1.py", "display": True},
"mitraille": {"OSC": 8015, "command": "python3 plugins/audio/mitraille.py", "display": True},
"livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True}, "livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True},
"ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py", "display": True}, "ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py", "display": True},
"ljwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py", "display": True}, "ljwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py", "display": True},

View File

@ -34,11 +34,11 @@ ip = 192.168.2.43
kpps = 25000 kpps = 25000
centerx = 0 centerx = 0
centery = 0 centery = 0
zoomx = 45.0 zoomx = 30.0
zoomy = 45.0 zoomy = 30.0
sizex = 32000 sizex = 32000
sizey = 32000 sizey = 32000
finangle = -30.0 finangle = 0
swapx = -1 swapx = -1
swapy = -1 swapy = -1
lsteps = [ (1.0, 2),(0.25, 1), (0.75, 1), (1.0, 5)] lsteps = [ (1.0, 2),(0.25, 1), (0.75, 1), (1.0, 5)]
@ -89,13 +89,7 @@ warpdest = [[-1500., 1500.],
[plugins] [plugins]
plugins = { plugins = {
"trckr": {"OSC": 8017, "command": "python3 plugins/VJing/trckr.py", "display": True},
"aurora": {"OSC": 8090, "command": "python3 plugins/aurora/aurora.py", "display": True}, "aurora": {"OSC": 8090, "command": "python3 plugins/aurora/aurora.py", "display": True},
"maxw": {"OSC": 8012, "command": "python3 plugins/maxwell.py", "display": True},
"square": {"OSC": 8013, "command": "python3 plugins/square.py", "display": True},
"custom1": {"OSC": 8014, "command": "python3 plugins/custom1.py", "display": True},
"mitraille": {"OSC": 8015, "command": "python3 plugins/audio/mitraille.py", "display": True},
"livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True},
"nozoid": {"OSC": 8003, "command": "python3 plugins/audio/nozoids3.py", "display": True}, "nozoid": {"OSC": 8003, "command": "python3 plugins/audio/nozoids3.py", "display": True},
"glyph": {"OSC": 8004, "command": "python3 plugins/laserglyph.py", "display": True}, "glyph": {"OSC": 8004, "command": "python3 plugins/laserglyph.py", "display": True},
"planet": {"OSC": 8005, "command": "python3 plugins/planetarium/main.py", "display": True}, "planet": {"OSC": 8005, "command": "python3 plugins/planetarium/main.py", "display": True},
@ -103,6 +97,11 @@ plugins = {
"cycl": {"OSC": 8007, "command": "python3 plugins/textcycl.py", "display": True}, "cycl": {"OSC": 8007, "command": "python3 plugins/textcycl.py", "display": True},
"simu": {"OSC": 8008, "command": "python plugins/pysimu.py", "display": False}, "simu": {"OSC": 8008, "command": "python plugins/pysimu.py", "display": False},
"artnet": {"OSC": 8009, "command": "python3 libs3/artnet.py", "display": False}, "artnet": {"OSC": 8009, "command": "python3 libs3/artnet.py", "display": False},
"trckr": {"OSC": 8017, "command": "python3 plugins/trckr.py", "display": False},
"maxw": {"OSC": 8012, "command": "python3 plugins/maxwell.py", "display": True},
"square": {"OSC": 8013, "command": "python3 plugins/square.py", "display": True},
"custom1": {"OSC": 8014, "command": "python3 plugins/custom1.py", "display": True},
"mitraille": {"OSC": 8015, "command": "python3 plugins/audio/mitraille.py", "display": True},
"livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True}, "livecode": {"OSC": 8016, "command": "python3 plugins/livecoding.py", "display": True},
"ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py", "display": True}, "ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py", "display": True},
"ljwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py", "display": True}, "ljwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py", "display": True},

View File

@ -28,7 +28,7 @@ Important : for best performance LJ is meant to run in a dedicated computer espe
- Some Lasermapping ('alignment') like in videomapping. - Some Lasermapping ('alignment') like in videomapping.
- OSC and websocket commands. Very cool : LJ can script or be scripted. - OSC and websocket commands. Very cool : LJ can script or be scripted.
- Python3 - Python3
- Web User Interface in your browser : open www/index.html. Javascript is needed. By default it connect to localhost. If you want to control remotely, you need to change the uri line in LJ.js. - Web User Interface in your browser : open www/index.html. Javascript is needed. By default it connect to localhost. If you want to control remotely, you need edit webui choice : python3 configure.py
- Live WebUI extras : change debug level, restart plugin, rescan DACs,... - Live WebUI extras : change debug level, restart plugin, rescan DACs,...
- Status update every 0.5 seconds : every etherdream DAC state, number of buffer points sent,... - Status update every 0.5 seconds : every etherdream DAC state, number of buffer points sent,...
- "Optimisation" points automatically added, can be changed live for glitch art. Search "resampler" commands. - "Optimisation" points automatically added, can be changed live for glitch art. Search "resampler" commands.
@ -260,10 +260,14 @@ DrawDests() will take care of all your declared drawn elements/"objects" and Des
# Nannou etherdeam simulator aka visualiser # Nannou etherdeam simulator aka visualiser
# #
2 compiled nannou visualisers are included, one for Linux, one for macOS. It's pretty old version but much more compatible with "old" processors/computer. Nannou visualiser kind of emulate an etherdream and display in a window what a real laser draws.
2 compiled nannou visualisers are included, one for Linux, one for macOS. It's pretty old versions but much more compatible with "old" processors/computer, as you may want to repurpose an old computer to run LJ.
To use this visualiser as one of LJ's lasers, in LJ.conf edit one of line ip = someipaddress with the IP of the computer running the visualiser. Relaunch LJ. One visualiser per computer. To use this visualiser as one of LJ's lasers, in LJ.conf edit one of line ip = someipaddress with the IP of the computer running the visualiser. Relaunch LJ. One visualiser per computer.
Nannou visualiser emulation is better and better but one can find a few known non-working situations. See it's github repository (https://github.com/nannou-org/ether-dream/tree/master/dac-emulator) for more recent versions.
# #
# Todo # Todo
# #
@ -349,9 +353,9 @@ About hardware setup, especially if you have several lasers : ILDA cables are in
# Ethertools directory # Ethertools directory
# #
2 useful and always working tools from j4cdac github repository : sitter and talk 2 useful and *always working tools* from j4cdac github repository : sitter and talk.
- Sitter will display all real etherdreams available on the network and their state (playing, idle,...). python sitter.py or use the compiled version (for macOS). - Sitter will display all etherdreams available on the network and their state (playing, idle,...). python sitter.py or use the compiled version (for macOS). May need tkinter : pip3 install tk
- Talk : will draw a 4 colors square. python3 talk3.py - Talk : will draw a 4 colors square. Try : python3 talk3.py -h
# #
# Links # Links
@ -367,6 +371,8 @@ Generic :
![Laser Faq](https://www.repairfaq.org/sam/lasersam.htm) ![Laser Faq](https://www.repairfaq.org/sam/lasersam.htm)
![Etherdream protocol](https://ether-dream.com/protocol.html)
There is a nice websocket debug tool : websocat. There is a nice websocket debug tool : websocat.
# #

View File

@ -9,7 +9,7 @@ BOOM | WIIIIIZ :: PHHHHHRACKRACKRACK ~~ WOOP ~~###~~ WIIT
## The basic loop ## The basic loop
``` ```
python3 generators/dummy.py -f 2 | filters/kaleidoscope.py | exports/toRedis.py -v python3 generators/dummy.py -f 2 | python3 filters/kaleidoscope.py | python3 exports/toRedis.py -v
------------------------------ --------------------- ------------------- ------------------------------ --------------------- -------------------
\/ \/ \/ \/ \/ \/
Generator Filter Export Generator Filter Export

View File

@ -165,7 +165,7 @@ class DAC(object):
return self.readresp("d") return self.readresp("d")
def prepare(self): def prepare(self):
self.conn.sendall('p') self.conn.sendall(b'p')
return self.readresp('p') return self.readresp('p')
def stop(self): def stop(self):

View File

@ -1,4 +1,17 @@
#!/usr/bin/env python #!/usr/bin/env python
'''
Improved dac.py and talk.py (by Jacob Potter). Pimped by Sam Neurohack.
- python3
- works with nannou visualisers
- can talk to a given etherdream knowing it's IP.
v0.1.0
'''
# #
# j4cDAC test code # j4cDAC test code
# #
@ -17,6 +30,19 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import dac3 as dac import dac3 as dac
import argparse
import sys
argsparser = argparse.ArgumentParser(description="Draw a square on a laser via Etherdream DAC")
argsparser.add_argument("-i","--ip",help="Etherdream IP (default : first etherdream broadcast received",default="True",type=str)
args = argsparser.parse_args()
etherIP = args.ip
class SquarePointStream(object): class SquarePointStream(object):
''' '''
@ -88,8 +114,14 @@ class NullPointStream(object):
return [(0, 0, 0, 0, 0)] * n return [(0, 0, 0, 0, 0)] * n
#dac.find_dac() #dac.find_dac()
if etherIP == "True":
print("Waiting for the first DAC broadcast...")
d = dac.DAC(dac.find_first_dac())
d = dac.DAC(dac.find_first_dac()) else:
#d = dac.DAC("192.168.1.43") print("Using Etherdream :", etherIP)
d = dac.DAC(etherIP)
print("Sending points...")
d.play_stream(SquarePointStream()) d.play_stream(SquarePointStream())

View File

@ -25,15 +25,15 @@ ljpath = r'%s' % os.getcwd().replace('\\','/')
# import from shell # import from shell
sys.path.append(ljpath +'/../libs/') sys.path.append(ljpath +'/../libs3/')
#import from LJ #import from LJ
sys.path.append(ljpath +'/libs/') sys.path.append(ljpath +'/libs3/')
print(ljpath+'/../libs/') print(ljpath+'/../libs3/')
import lj23layers as lj import lj23layers as lj
sys.path.append('../libs') sys.path.append('../libs3')
from OSC3 import OSCServer, OSCClient, OSCMessage from OSC3 import OSCServer, OSCClient, OSCMessage
import redis import redis
import math import math

View File

@ -25,15 +25,15 @@ ljpath = r'%s' % os.getcwd().replace('\\','/')
# import from shell # import from shell
sys.path.append(ljpath +'/../libs/') sys.path.append(ljpath +'/../libs3/')
#import from LJ #import from LJ
sys.path.append(ljpath +'/libs/') sys.path.append(ljpath +'/libs3/')
print(ljpath+'/../libs/') print(ljpath+'/../libs3/')
import lj23layers as lj import lj23layers as lj
sys.path.append('../libs') sys.path.append('../libs3')
from OSC3 import OSCServer, OSCClient, OSCMessage from OSC3 import OSCServer, OSCClient, OSCMessage
import redis import redis
import math import math

647
plugins/trckr.py Normal file
View File

@ -0,0 +1,647 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# -*- mode: Python -*-
'''
trckr
Work with clmtrackr-dev and www/trckr/trckr.html
v0.1.0
LICENCE : CC
by Sam Neurohack
To test the examples locally, you need to run a local server.
One easy way to do this is to install http-server, a small node.js utility:
npm install -g http-server.
Then run http-server in the root of clmtrackr and go to
- read a video :
http://localhost:8080/examples/trckr.html
- webcam
clmtrackr :
https://github.com/auduno/clmtrackr/tree/dev/examples
'''
import sys
import os
print()
ljpath = r'%s' % os.getcwd().replace('\\','/')
# import from shell
sys.path.append(ljpath +'/../libs3/')
#import from LJ
import log
print ("")
log.infog("Trckr Plugin v0.1")
sys.path.append('../libs3')
sys.path.append(ljpath +'/../../libs3')
from OSC3 import OSCServer, OSCClient, OSCMessage
import lj23layers as lj
import redis
import math
import time
import argparse
OSCinPort = 8017
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="trckr 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)
# 3D to 2D projection parameters
fov = 256
viewer_distance = 2.2
width = 800
height = 600
centerX = width / 2
centerY = height / 2
TrckrPts = [[0,0]] * 70
#
# LJ inits
#
layer = 0
# Setup LJ library mandatory properties for this layerugin
lj.Config(redisIP, ljscene, "trckr")
# Define properties for each drawn "element" : name, intensity, active, xy, color, red, green, blue, layer , closed
FaceForm = lj.FixedObject('Face', True, 255, [], red, 255, 0, 0, layer , False)
# '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
#
# 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
# /trckr/ljscene
def OSCljscene(path, tags, args, source):
print("Got /trckr/ljscene with value", args[0])
lj.WebStatus("trckr to virtual "+ str(args[0]))
ljscene = args[0]
lj.Ljscene(ljscene)
# /trckr/layer
def OSClayer(path, tags, args, source):
print()
print()
print("Got /trckr/layer with value", args[0])
lj.WebStatus("trckr to layer "+ str(args[0]))
FaceForm.layer = int(args[0])
Dest0.layer = int(args[0])
Dest0.laser = int(args[0])
# /trckr/frame
def OSCtrckr(path, tags, args, source):
global TrckrPts
#print("trckr got frame", args[0])
if debug != 0:
print("trckr plugin got frame", args[0])
print(len(args),"args", args)
counter =0
TrckrPts = []
for dot in range(1,len(args)-1,2):
TrckrPts.append([float(args[dot]), float(args[dot+1])])
print(TrckrPts)
# /trckr/frame layernumber framenumber points
def OSCTrckrframe(path, tags, args, source):
global TrckrPts
if debug != 0:
print("trckr plugin got frame", args[1], "for layer", args[0], "with path", path)
print(len(args),"args", args)
TrckrPts[args[0]] = []
for dot in range(2,len(args)-1,2):
TrckrPts[args[0]].append([float(args[dot]), float(args[dot+1])])
#/trckr/color/0 red ?
def OSColor():
global FaceForm
if debug != 0:
print("trckr color got ", args[1], "for layer", args[0], "with path", path)
print(len(args),"args", args)
FaceForm.color = args[1]
# default handler
def OSChandler(path, tags, args, source):
oscaddress = ''.join(path.split("/"))
print()
print("trckr default OSC Handler :", path, "from Client :" + str(source[0]))
#
# Face Tracking
#
# get absolute face position points
def getPART(pose_points):
dots = []
for dot in pose_points:
dots.append((TrckrPts[dot][0], TrckrPts[dot][1],0))
return dots
# Face keypoints
def face():
pose_points = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
return getPART(pose_points)
def browL():
pose_points = [15,16,17,18]
return getPART(pose_points)
def browR():
pose_points = [22,21,20,19]
return getPART(pose_points)
def eyeR():
pose_points = [25,64,24,63,23,66,26,65,25]
return getPART(pose_points)
def eyeL():
pose_points = [28,67,29,68,30,69,31,28]
return getPART(pose_points)
def pupR():
pose_points = [27]
return getPART(pose_points)
def pupL():
pose_points = [32]
return getPART(pose_points)
def nose1():
pose_points = [62,41,33]
return getPART(pose_points)
def nose2():
pose_points = [40,39,38,43,37,42,36,35,34]
return getPART(pose_points)
def mouth():
pose_points = [50,49,48,47,46,45,44,55,54,53,52,51,50]
return getPART(pose_points)
def mouthfull():
pose_points = [50,49,48,47,46,45,44,55,54,53,52,51,50,59,60,61,44,56,57,58,50]
return getPART(pose_points)
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():
Facepts = []
counter =0
lj.WebStatus("trckr")
lj.SendLJ("/trckr/start 1")
# OSC Server callbacks
print("Starting OSC server at",myIP," port",OSCinPort,"...")
oscserver.addMsgHandler( "/trckr/ljscene", OSCljscene)
oscserver.addMsgHandler( "/trckr/layer", OSClayer)
oscserver.addMsgHandler( "/trckr/frame", OSCtrckr)
oscserver.addMsgHandler( "/trckr/color", OSColor)
# Add OSC generic layerugins commands : 'default", /ping, /quit, /pluginame/obj, /pluginame/var, /pluginame/adddest, /pluginame/deldest
lj.addOSCdefaults(oscserver)
oscserver.addMsgHandler( "default", OSChandler )
try:
while lj.oscrun:
lj.OSCframe()
#print("browL", browL(), "browR", browR(), "nose1", nose1(), "mouth", mouth())
lj.rPolyLineOneColor(browL(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(eyeL(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(browR(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(eyeR(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(pupL(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(pupR(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(nose1(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(nose2(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.rPolyLineOneColor(mouthfull(), c = FaceForm.color, layer = FaceForm.layer, closed = FaceForm.closed, xpos = -300, ypos = -300, resize = 3.6, rotx = 0, roty = 0, rotz = 0)
lj.DrawDests()
time.sleep(0.005)
counter += 1
if counter > 360:
counter = 0
except KeyboardInterrupt:
pass
# Gently stop on CTRL C
finally:
lj.ClosePlugin()
Run()
'''
//
// a template for receiving face tracking osc messages from
// Kyle McDonald's trckr https://github.com/kylemcdonald/ofxFaceTracker
//
// 2012 Dan Wilcox danomatika.com
// for the IACD Spring 2012 class at the CMU School of Art
//
// adapted from from Greg Borenstein's 2011 example
// http://www.gregborenstein.com/
// https://gist.github.com/1603230
//
//Xavier Apostol
//Generative Faces: Plotter Project Concept
import oscP5.*;
OscP5 oscP5;
// num faces found
int found;
// pose
float poseScale;
PVector posePosition = new PVector();
PVector poseOrientation = new PVector();
// gesture
float mouthHeight;
float mouthWidth;
float eyeLeft;
float eyeRight;
float eyebrowLeft;
float eyebrowRight;
float jaw;
float nostrils;
float sz = 1;
float spacing = 100;
float genSz = spacing/4;
float fcOff = genSz/2;
//Initialization of Colors
float R = random(255);
float G = random(255);
float B = random(255);
//Initialization of Head
float rotInt = 15;
float hdX = cos(sz) + random(genSz, 3*genSz);
float hdY = sin(sz) + random(genSz, 3*genSz);
float rotAngle = random(-rotInt,rotInt);
//Initialization of Eyes
float lEyeX1 = sin(sz*0) + random(genSz);
float lEyeY1 = cos(sz*0) + random(genSz);
float rEyeX1 = sin(sz*0) + random(genSz);
float rEyeY1 = cos(sz*0) + random(genSz);
float lEyeX2 = sin(sz*1) + random(genSz);
float lEyeY2 = cos(sz*1) + random(genSz);
float rEyeX2 = sin(sz*1) + random(genSz);
float rEyeY2 = cos(sz*1) + random(genSz);
float ranREye = random(7, 9);
float ranLEye = random(7, 9);
//Initialization of Mouth
float mthX = cos(sz) + random(genSz);
float mthY = sin(sz) + random(genSz);
float ranM = random(-0.1, 1.5);
//Initialization of Spine
float hdOffset = hdY/1.5;
float spineSz = random(genSz/2);
float spXOff1 = random(-8, 8);
float spYOff1 = hdOffset + random(genSz/3);
float spXOff2 = random(-8, 8)+spXOff1;
float spYOff2 = random(genSz/3)+spYOff1;
float spXOff3 = random(-8, 8)+spXOff2;
float spYOff3 = random(genSz/3)+spYOff2;
float spXOff4 = random(-8, 8)+spXOff3;
float spYOff4 = random(genSz/3)+spYOff3;
float spXOff5 = random(-8, 8)+spXOff4;
float spYOff5 = random(genSz/3)+spYOff4;
void setup() {
size(800, 600, OPENGL);
frameRate(30);
oscP5 = new OscP5(this, 8338);
oscP5.plug(this, "found", "/found");
oscP5.plug(this, "poseScale", "/pose/scale");
oscP5.plug(this, "posePosition", "/pose/position");
oscP5.plug(this, "poseOrientation", "/pose/orientation");
oscP5.plug(this, "mouthWidthReceived", "/gesture/mouth/width");
oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height");
oscP5.plug(this, "eyeLeftReceived", "/gesture/eye/left");
oscP5.plug(this, "eyeRightReceived", "/gesture/eye/right");
oscP5.plug(this, "eyebrowLeftReceived", "/gesture/eyebrow/left");
oscP5.plug(this, "eyebrowRightReceived", "/gesture/eyebrow/right");
oscP5.plug(this, "jawReceived", "/gesture/jaw");
oscP5.plug(this, "nostrilsReceived", "/gesture/nostrils");
}
void keyPressed() {
if (key == CODED) {
if (keyCode == UP) {
//Create an entirely new character.
//For Eyes
lEyeX1 = sin(sz*0) + random(genSz);
lEyeY1 = cos(sz*0) + random(genSz);
rEyeX1 = sin(sz*0) + random(genSz);
rEyeY1 = cos(sz*0) + random(genSz);
lEyeX2 = sin(sz*1) + random(genSz);
lEyeY2 = cos(sz*1) + random(genSz);
rEyeX2 = sin(sz*1) + random(genSz);
rEyeY2 = cos(sz*1) + random(genSz);
ranREye = random(7, 9);
ranLEye = random(7, 9);
//For Mouth
mthX = cos(sz) + random(genSz);
mthY = sin(sz) + random(genSz);
ranM = random(-0.1, 1.5);
//For Spine
spineSz = random(genSz/2);
spXOff1 = random(-8, 8);
spYOff1 = hdOffset + random(genSz/3);
spXOff2 = random(-8, 8) + spXOff1;
spYOff2 = random(genSz/3) + spYOff1;
spXOff3 = random(-8, 8) + spXOff2;
spYOff3 = random(genSz/3) + spYOff2;
spXOff4 = random(-8, 8) + spXOff3;
spYOff4 = random(genSz/3) + spYOff3;
spXOff5 = random(-8, 8) + spXOff4;
spYOff5 = random(genSz/3) + spYOff4;
//For Head
hdX = cos(sz) + random(genSz, 3*genSz);
hdY = sin(sz) + random(genSz, 3*genSz);
rotAngle = random(-rotInt,rotInt);
//For Colors
R = random(255);
G = random(255);
B = random(255);
draw();
}
}
}
void draw() {
background(0);
strokeWeight(1);
noFill();
if(found != 0) {
pushMatrix();
translate(posePosition.x, posePosition.y);
//Scales head and allows for rotations
scale(poseScale*2);
rotateY(0 - poseOrientation.y);
rotateX(0 - poseOrientation.x);
rotateZ(poseOrientation.z);
rotate(radians(rotAngle));
ellipse(0,0, hdX,hdY);
popMatrix();
//FACE
translate(posePosition.x, posePosition.y);
scale(poseScale);
noFill();
//Eyes
float eyeFac = 1;
float eyeBL = eyebrowLeft * 2;
float eyeBR = eyebrowRight * 2;
ellipse(-20,eyeLeft * -ranLEye, lEyeX1*eyeFac + eyeBL,lEyeY1*eyeFac + eyeBL);
ellipse(20,eyeRight * -ranREye, rEyeX1*eyeFac + eyeBR,rEyeY1*eyeFac + eyeBR);
ellipse(-20,eyeLeft * -ranLEye, lEyeX2*eyeFac + eyeBL,lEyeY2*eyeFac + eyeBL);
ellipse(20,eyeRight * -ranREye, rEyeX2*eyeFac + eyeBR,rEyeY2*eyeFac + eyeBR);
//Mouth
ellipse(0, 20*ranM, mouthWidth* mthX/3, mouthHeight * mthY);
//BODY/BUBBLES
stroke(R,G,B);
ellipse(spXOff1,spYOff1, spineSz,spineSz);
ellipse(spXOff2,spYOff2, spineSz,spineSz);
ellipse(spXOff3,spYOff3, spineSz,spineSz);
ellipse(spXOff4,spYOff4, spineSz,spineSz);
ellipse(spXOff5,spYOff5, spineSz,spineSz);
}
}
// OSC CALLBACK FUNCTIONS
public void found(int i) {
println("found: " + i);
found = i;
}
public void poseScale(float s) {
println("scale: " + s);
poseScale = s;
}
public void posePosition(float x, float y) {
println("pose position\tX: " + x + " Y: " + y );
posePosition.set(x, y, 0);
}
public void poseOrientation(float x, float y, float z) {
println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z);
poseOrientation.set(x, y, z);
}
public void mouthWidthReceived(float w) {
println("mouth Width: " + w);
mouthWidth = w;
}
public void mouthHeightReceived(float h) {
println("mouth height: " + h);
mouthHeight = h;
}
public void eyeLeftReceived(float f) {
println("eye left: " + f);
eyeLeft = f;
}
public void eyeRightReceived(float f) {
println("eye right: " + f);
eyeRight = f;
}
public void eyebrowLeftReceived(float f) {
println("eyebrow left: " + f);
eyebrowLeft = f;
}
public void eyebrowRightReceived(float f) {
println("eyebrow right: " + f);
eyebrowRight = f;
}
public void jawReceived(float f) {
println("jaw: " + f);
jaw = f;
}
public void nostrilsReceived(float f) {
println("nostrils: " + f);
nostrils = f;
}
// all other OSC messages end up here
void oscEvent(OscMessage m) {
if(m.isPlugged() == false) {
println("UNPLUGGED: " + m);
}
}
'''

View File

@ -25,6 +25,7 @@ sudo apt install libjack-dev
pip3 install python-rtmidi pip3 install python-rtmidi
pip3 install mido pip3 install mido
git clone https://github.com/ptone/pyosc --depth 1 /tmp/pyosc && cd /tmp/pyosc && sudo ./setup.py install git clone https://github.com/ptone/pyosc --depth 1 /tmp/pyosc && cd /tmp/pyosc && sudo ./setup.py install
pip3 install tk
cd ../ cd ../
python3 configure.py python3 configure.py
# todo : ask for computer ip and run updateUI.py # todo : ask for computer ip and run updateUI.py

View File

@ -21,7 +21,7 @@ brew install libasound2-dev
brew install libjack-dev brew install libjack-dev
pip3 install python-rtmidi pip3 install python-rtmidi
pip3 install mido pip3 install mido
#pip3 install tk
cd ../ cd ../
python3 configure.py python3 configure.py
#sudo cp syncthing.conf to /etc/supervisor/conf.d/ #sudo cp syncthing.conf to /etc/supervisor/conf.d/

View File

@ -60,6 +60,7 @@ def www(wwwip):
print("Updating www files to use", wwwIP) print("Updating www files to use", wwwIP)
Updatepage(ljpath+"/www/LJ.js") Updatepage(ljpath+"/www/LJ.js")
Updatepage(ljpath+"/www/trckr/trckrcam1.html") Updatepage(ljpath+"/www/trckr/trckrcam1.html")
Updatepage(ljpath+"/www/trckr/trckr.html")
Updatepage(ljpath+"/www/simu.html") Updatepage(ljpath+"/www/simu.html")
Updatepage(ljpath+"/www/align.html") Updatepage(ljpath+"/www/align.html")
Updatepage(ljpath+"/www/auralls.html") Updatepage(ljpath+"/www/auralls.html")

View File

@ -1,5 +1,21 @@
clmtrackr = Web Interface
======
You can load index.html file from your browser or have a webserver of your choice pointing to this directory.
Webserver is mandatory if you want :
- to remotely control LJ : imagine LJ can be installed in a dedicated computer/container with no easy access.
- to use the face tracking, say from a smartphone. That's Lasercam (a clmtrackr plugin).
== Simu
A laser simulator. Choose lasernumber and it will display redis points for current scene/lasernumber
== clmtrackr
[![npm version](https://img.shields.io/npm/v/clmtrackr.svg)](https://www.npmjs.com/package/clmtrackr) [![npm version](https://img.shields.io/npm/v/clmtrackr.svg)](https://www.npmjs.com/package/clmtrackr)

View File

@ -300,16 +300,6 @@
console.log("/laser "+res[1]) console.log("/laser "+res[1])
newlaser(res[1]) newlaser(res[1])
break; break;
case "/lack/":
console.log("/lack "+res[1])
document.getElementById(res[0].slice(1)).value = res[1];
break;
case "/lstt/":
console.log("/lstt "+res[1])
document.getElementById(res[0].slice(1)).value = res[1];
break;
default: default:

View File

@ -287,17 +287,6 @@
case "/plpoi": case "/plpoi":
//console.log("plpoint"); //console.log("plpoint");
break; break;
case "/lack/":
console.log("/lack "+res[1])
document.getElementById(res[0].slice(1)).value = res[1];
break;
case "/lstt/":
console.log("/lstt "+res[1])
document.getElementById(res[0].slice(1)).value = res[1];
break;
default: default:
//console.log("test "+res[0].slice(1)+" "+res[1]); //console.log("test "+res[0].slice(1)+" "+res[1]);
document.getElementById(res[0].slice(1)).value = res[1]; document.getElementById(res[0].slice(1)).value = res[1];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

679
www/trckr/trckr.html Normal file
View File

@ -0,0 +1,679 @@
<!doctype html>
<html lang="en">
<head>
<title>LASERCam 1</title>
<meta charset="utf-8">
<link href="./styles/bootstrap.min.css" rel="stylesheet" type="text/css">
<meta name="apple-mobile-web-app-title" content="Tracker">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="apple-touch-startup-image" href="../launch.png">
<link rel="apple-touch-icon" href="../touch-icon-iphone.png">
<link rel="apple-touch-icon" sizes="152x152" href="../touch-icon-ipad.png">
<link rel="apple-touch-icon" sizes="180x180" href="../touch-icon-iphone-retina.png">
<link rel="apple-touch-icon" sizes="167x167" href="../touch-icon-ipad-retina.png">
<style>
</style>
<script>
// getUserMedia only works over https in Chrome 47+, so we redirect to https. Also notify user if running from file.
if (window.location.protocol == "file:") {
alert("You seem to be running this example directly from a file. Note that these examples only work when served from a server or localhost due to canvas cross-domain restrictions.");
} else if (window.location.hostname !== "localhost" && window.location.protocol !== "https:"){
window.location.protocol = "http";
//window.location.protocol = "https";
}
</script>
<!--
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-32642923-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
-->
<!-- Web audio buttons defaults -->
<script type="application/javascript" src="../webcomponents-lite.js"></script>
<script>
WebAudioControlsOptions={
useMidi:1,
knobSrc:"knobs/simplegray.png",
knobSprites:100,
switchSrc:"knobs/switch_toggle.png",
sliderSrc:"knobs/vsliderbody.png",
sliderKnobsrc:"knobs/vsliderknob.png",
}
</script>
<script src="../webaudio-controls.js"></script>
<!-- link rel="stylesheet" href="LJgrid.css" / -->
<link rel="stylesheet" type="text/css" href="../selector.min.css">
<script type="application/javascript" src="../selector.min.js"></script>
<link rel="stylesheet" href="../css/common.css" />
</head>
<body style="background-color:#222;">
<script src="./js/libs/utils.js"></script>
<script src="../build/clmtrackr.js"></script>
<script src="./js/libs/Stats.js"></script>
<!--
Top Rack
<div align="center">
<a href="index.html"><img height="25" width="21" src="../knobs/indexs.png"></a>
</div>
-->
<div class="Rackcontent">
<!--
Navigation Rack
-->
<div class="content">
<div class="buttons-7container">
<a href="../index.html">
<div class="webaudiobut">
<div align="center" class="navled">
Index
</div>
</div>
</a>
<a href="../align.html">
<div class="webaudiobut">
<div align="center" class="navled">
Align
</div>
</div>
</a>
<a href="../auralls.html">
<div class="webaudiobut">
<div align="center" class="navled">
Aurora
</div>
</div>
</a>
<a href="trckrcam1.html">
<div class="webaudiobut">
<div align="center" class="navled">
Lasercam
</div>
</div>
</a>
<a href="../simu.html">
<div class="webaudiobut">
<div align="center" class="navled">
Simu
</div>
</div>
</a>
<div class="webaudiobut">
<button type="button" class="navled" style="border : #222222 1px;" onclick="onSubmit(this.id)" id="settings/restart lj" >
rstrt LJ
</button>
</div>
<div class="webaudiobut">
<button type="button" class="navled" style="border : #222222 1px;" onclick="onSubmit(this.id)" id="settings/restart aurora" >
rstrt AU
</button>
</div>
</div>
</div>
<!--
Lasers & colors Rack
-->
<div class="content">
<div class="TopRackGrid">
<div>
<h2>
/TL RGY 1
<span class="shade">&nbsp;</span>
</h2>
<webaudio-switch id="on" value="1" tooltip="Switch-B" height="35" width="85" src="../knobs/switch1.png">
</webaudio-switch>
</div>
<div style="border : #242424 1px solid;background: #000;">
<div align="center" id="line1" class="busled">
LASERcam 1 : Allow to use your webcam + start
</div>
<div align="center" id="status" class="busled">
/team/laser
</div>
</div>
<div></div>
<div>
<div style="margin-top : 30px;">
</div>
<div>
</div>
</div>
</div>
</div>
<!--
Colors Rack
-->
<div class="content">
<div class="Rackgrid">
<div>
<h2>
Colors
</h2>
</div>
<div class="webaudiobut"><webaudio-switch id="noteon 24" value="1" tooltip="Switch-B" height="64" width="64" src="../knobs/big0.png"></webaudio-switch></div>
<div class="webaudiobut"><webaudio-switch id="noteon 25" value="0" tooltip="Switch-B" height="64" width="64" src=" ../knobs/big1.png"></webaudio-switch></div>
<div class="webaudiobut"><webaudio-switch id="noteon 26" value="0" tooltip="Switch-B" height="64" width="64" src="../knobs/big2.png"></webaudio-switch></div>
<div class="webaudiobut"><webaudio-switch id="noteon 27" value="0" tooltip="Switch-B" height="64" width="64" src="../knobs/big3.png"></webaudio-switch></div>
<div></div>
<div class="webaudiobut"><webaudio-switch id="trckr/color/0 red" value="1" tooltip="Switch-B" height="64" width="64" src="knobs/red.png"></webaudio-switch></div>
<div class="webaudiobut"><webaudio-switch id="trckr/color/0 yellow" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/yellow.png"></webaudio-switch></div>
<div class="webaudiobut"><webaudio-switch id="trckr/color/0 green" value="0" tooltip="Switch-B" height="64" width="64" src="knobs/green.png"></webaudio-switch></div>
<div></div>
</div>
</div>
<!--
Webcam Rack
-->
<div class="content" style="background-image: linear-gradient(174deg, #111,#030303);">
<video id="videoel" class="webaudiobut" width="400" height="300" preload="auto" loop playsinline autoplay>
</video>
<canvas id="overlay" width="400" height="300"></canvas>
<input class="btn" type="button" value="wait" style="margin-left: 150px;" disabled="disabled" onclick="startVideo()" id="startbutton"></input>
</div>
<!--
Big Display Rack
-->
<div class="content">
<div id="text" class="busled" style="font-size:1.5em;border : #242424 1px solid;background: #000;-webkit-box-shadow: 4px 6px 10px -1px rgba(0,0,0,0.72);-moz-box-shadow: 4px 6px 10px -1px rgba(0,0,0,0.72);box-shadow: 4px 6px 10px -1px rgba(0,0,0,0.72);">
<div id="gum" class="gum">
<p>To try it out:
<ol>
<li>Allow the page to use your webcamera</li>
<li>Make sure that your face is clearly visible in the video, and click start</li>
<li>See the model fitted to your face</li>
<ol>
</p>
</div>
<div id="nogum" class="nogum">
</div>
</div>
</div>
</div>
<!--
JS
-->
<script>
var vid = document.getElementById('videoel');
var vid_width = vid.width;
var vid_height = vid.height;
var overlay = document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');
/*********** Setup of video/webcam and checking for webGL support *********/
function enablestart() {
var startbutton = document.getElementById('startbutton');
startbutton.value = "start";
startbutton.disabled = null;
}
var insertAltVideo = function(video) {
// insert alternate video if getUserMedia not available
if (supports_video()) {
if (supports_webm_video()) {
video.src = "./media/cap12_edit.webm";
} else if (supports_h264_baseline_video()) {
video.src = "./media/cap12_edit.mp4";
} else {
return false;
}
return true;
} else return false;
}
function adjustVideoProportions() {
// resize overlay and video if proportions of video are not 4:3
// keep same height, just change width
var proportion = vid.videoWidth/vid.videoHeight;
vid_width = Math.round(vid_height * proportion);
vid.width = vid_width;
overlay.width = vid_width;
}
function gumSuccess( stream ) {
// add camera stream if getUserMedia succeeded
if ("srcObject" in vid) {
vid.srcObject = stream;
} else {
vid.src = (window.URL && window.URL.createObjectURL(stream));
}
vid.onloadedmetadata = function() {
adjustVideoProportions();
vid.play();
}
vid.onresize = function() {
adjustVideoProportions();
if (trackingStarted) {
ctrack.stop();
ctrack.reset();
ctrack.start(vid);
}
}
}
function gumFail() {
// fall back to video if getUserMedia failed
insertAltVideo(vid);
document.getElementById('gum').className = "hide";
document.getElementById('nogum').className = "nohide";
}
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.msURL || window.mozURL;
// set up video
if (navigator.mediaDevices) {
navigator.mediaDevices.getUserMedia({video : true}).then(gumSuccess).catch(gumFail);
} else if (navigator.getUserMedia) {
navigator.getUserMedia({video : true}, gumSuccess, gumFail);
} else {
insertAltVideo(vid);
document.getElementById('gum').className = "hide";
document.getElementById('nogum').className = "nohide";
alert("Your browser does not seem to support getUserMedia, using a fallback video instead.");
}
vid.addEventListener('canplay', enablestart, false);
/*********** Code for face tracking *********/
var ctrack = new clm.tracker();
ctrack.init();
var trackingStarted = false;
var counter = 0;
var layer = 0;
function startVideo() {
// start video
vid.play();
// start tracking
ctrack.start(vid);
trackingStarted = true;
// start loop to draw face
drawLoop();
}
function drawLoop() {
requestAnimFrame(drawLoop);
overlayCC.clearRect(0, 0, vid_width, vid_height);
//psrElement.innerHTML = "score :" + ctrack.getScore().toFixed(4);
var positions = ctrack.getCurrentPosition();
// do something with the positions ...
// print the positions
var positionString = "";
var positionFace = 'trckr/frame '+layer+" "+counter+" ";
if (positions) {
ctrack.draw(overlay);
for (var p = 0;p < 71;p++) {
positionString += "featurepoint "+p+" : ["+positions[p][0].toFixed(2)+","+positions[p][1].toFixed(2)+"]<br/>";
positionFace += positions[p][0].toFixed(2)+" "+positions[p][1].toFixed(2)+" ";
}
//document.getElementById('positions').innerHTML = positionString;
_WS.s.send(positionFace);
counter +=1;
}
}
/*********** Code for stats **********/
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild( stats.domElement );
// update stats on every iteration
document.addEventListener('clmtrackrIteration', function(event) {
stats.update();
}, false);
</script>
<!-- LJ style WS : A nettoyer ! -->
<script type="text/javascript">
var LJ = 'ws://192.168.2.43:9001/'
var _WS = {
uri: LJ,
ws: null,
init : function (e) {
_WS.s = new WebSocket(_WS.uri);
_WS.s.onopen = function (e) { _WS.onOpen(e); };
_WS.s.onclose = function (e) { _WS.onClose(e); };
_WS.s.onmessage = function (e) { _WS.onMessage(e); };
_WS.s.onerror = function (e) { _WS.onError(e); };
},
onOpen: function () {
_WS.showstatus("Connected to "+LJ);
document.getElementById("on").value = 1;
},
onClose: function () {
_WS.showline1('<span style="color: red;">LJ DISCONNECTED</span> ');
},
onMessage: function (e) {
var res = e.data.split(" ");
//console.log(e.data)
//console.log(res[0].substring(0,6))
//console.log(res)
//console.log(res[0].slice(1))
var divtext = document.getElementById('status');
var divtextp = document.getElementById('players');
switch (res[0].substring(0,6)) {
case "/statu":
if (res[2]==="Disconnected"){
_WS.showstatus(res[1]+" "+'<span style="color: red;">'+ res[2]+'</span> ');
}
else{
_WS.showstatus(res[1]+" "+res[2]);
}
break;
case "/redst":
//console.log("red"+res[1]+" "+res[2]);
_WS.showstatus('<span style="color: red;">'+res[1]+" "+ res[2]+'</span> ');
break;
case "/line1":
//divtext.innerHTML="connected to "+LJ;
divtext1.innerHTML=res[1]+" "+res[2];
break;
case "/redline1":
//divtext.innerHTML="connected to "+LJ;
divtext1.innerHTML='<span style="color: red;">'+ res[1]+" "+res[2]+'</span>';
break;
case "/laser":
console.log("/laser "+res[1])
newlaser(res[1])
break;
case "/lack/":
console.log("/lack "+res[1])
document.getElementById(res[0].slice(1)).value = res[1];
break;
case "/lstt/":
console.log("/lstt "+res[1])
document.getElementById(res[0].slice(1)).value = res[1];
break;
default:
//console.log("test "+res[0].slice(1)+" "+res[1]);
document.getElementById(res[0].slice(1)).value = res[1];
//_WS.showstatus(e.data);
}
},
showline1: function (message) {
var divtext = document.getElementById('line1');
divtext.innerHTML="";
divtext.innerHTML= message.toString();
},
onError: function (e) {
_WS.showstatus('<span style="color: red;">ERROR:</span> ' + e.data);
},
showin: function (message) {
var divtext = document.getElementById('status');
divtext.innerHTML="";
divtext.innerHTML= message.toString();
},
showout: function (message) {
var divtext = document.getElementById('status');
divtext.innerHTML="";
divtext.innerHTML= message.toString();
},
showstatus: function (message) {
var divtext = document.getElementById('status');
divtext.innerHTML="";
divtext.innerHTML= message.toString();
},
send: function (message) {
if (!message.length) {
alert('Empty message not allowed !');
} else {
_WS.showstatus(message);
_WS.s.send(message);
}
},
close: function () {
_WS.showstatus('GOODBYE !');
_WS.s.close();
}
};
window.addEventListener('load', _WS.init, false);
//
// Forms submits
//
function onSubmit(clicked_id) {
var input = document.getElementById(clicked_id);
console.log("/" + clicked_id + " " + input.value);
_WS.send("/" + clicked_id + " " + input.value);
}
</script>
<!--
web audio encoders scripts
-->
<script type="text/javascript">
var message="";
var log=[];
var knobs = document.getElementsByTagName('webaudio-knob');
for(var i = 0; i < knobs.length; i++){
knobs[i].addEventListener("input",Dump,false);
knobs[i].addEventListener("change",Dump,false);
}
var sliders = document.getElementsByTagName('webaudio-slider');
for(var i = 0; i < sliders.length; i++){
sliders[i].addEventListener("input",Dump,false);
sliders[i].addEventListener("change",Dump,false);
}
var switches = document.getElementsByTagName('webaudio-switch');
for(var i = 0; i < switches.length; i++) {
switches[i].addEventListener("change",Dump,false);
}
function newlaser(id) {
console.log("newlaser " +id)
var laserid = 24+ parseInt(id,10);
laser = "noteon "+laserid;
console.log("laser "+laser);
nolaser();
nofx();
var x = document.getElementById(laser);
x.value = 1 ;
}
function nolaser() {
//console.log("nolaser")
var x = document.getElementById("noteon 24");
x.value = 0 ;
var x = document.getElementById("noteon 25");
x.value = 0 ;
var x = document.getElementById("noteon 26");
x.value = 0 ;
var x = document.getElementById("noteon 27");
x.value = 0 ;
}
// RGB Colors
function nocolor() {
//console.log("nocolor0")
var x = document.getElementById("trckr/color/ red");
x.value = 0 ;
var x = document.getElementById("trckr/color/ yellow");
x.value = 0 ;
var x = document.getElementById("trckr/color/ green");
x.value = 0 ;
var x = document.getElementById("trckr/color/ blue");
x.value = 0 ;
var x = document.getElementById("trckr/color/ cyan");
x.value = 0 ;
var x = document.getElementById("trckr/color/ white");
x.value = 0 ;
}
// RGY Colors
//function nocolor() {
//var x = document.getElementById("trckr/color/ red");
// x.value = 0 ;
//var x = document.getElementById("trckr/color/ yellow");
// x.value = 0 ;
//var x = document.getElementById("trckr/color/ green");
// x.value = 0 ;
//}
function Dump(e) {
var str="";
str=e.type + " : " + e.target.id + " : " + e.target.value + " ";
console.log(str);
log.unshift(str);
log.length=1;
str="";
for(var i=19;i>=0;--i) {
if(log[i])
str+=log[i]+"<br/>";
}
_WS.send("/" + e.target.id + " " + e.target.value);
var res = e.target.id.split(" ");
// on off
if (e.target.id === "on" && e.type === "change") {
window.location.reload();
}
// Go to index
if (e.target.id === "index" && e.type === "change") {
window.location.assign("../index.html");
}
// Fx
if (res[0].substring(7,9) === "fx" && e.type === "change") {
var layer = res[0].substring(10,12);
nofx0();
var x = document.getElementById(e.target.id);
x.value = 1 ;
_WS.showstatus(e.target.id);
}
// Colors
if (res[0].substring(7,9) === "co" && e.type === "change") {
nocolor();
_WS.send("/"+res[0]+laser+ " "+ res[1]+ " " + e.target.value);
var x = document.getElementById(e.target.id);
x.value = 1 ;
//_WS.showstatus("Laser "+laser+ " "+ res[1]);
console.log("colors sending "+res[0]+laser+ " "+ res[1]+ " " + e.target.value);
}
// Lasers
if (res[0] === "noteon" && e.type === "change") {
//console.log(e.target.id);
//console.log(res);
//console.log(res[1] - 24)
newlaser(res[1] - 24);
_WS.send("/" + e.target.id + " " + e.target.value);
//nolaser();
//nofx();
//_WS.send("/" + e.target.id + " " + e.target.value);
//var x = document.getElementById(e.target.id);
//x.value = 1 ;
//laser = res[1] - 24;
//console.log("laser "+laser);
}
</script>
</body>
</html>