Skip to content

Instantly share code, notes, and snippets.

@akirayou
Created October 29, 2018 22:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akirayou/91e2935ed2b58c463b7f5e6c63c55e65 to your computer and use it in GitHub Desktop.
Save akirayou/91e2935ed2b58c463b7f5e6c63c55e65 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Globalization;
using System.Net.Sockets;
public partial class Data
{
[JsonProperty("level")]
public float[][] Level { get; set; }
[JsonProperty("pos")]
public float[][][] Pos { get; set; }
[JsonProperty("host")]
public string[] Host { get; set; }
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
public class Igniter
{
string Host;
UdpClient udp;
public Igniter(string _host)
{
Init(_host);
}
public void Init(string host)
{
Host = host;
udp =new UdpClient();
udp.Connect(Host, 13531);
Debug.Log(Host);
}
public void Send(byte a)
{
byte[] d = new byte[1];
d[0] = a;
Debug.Log("send ignitger" + a.ToString());
udp.Send(d, d.Length);
}
}
public class UnitData
{
string Host;
byte[] Led;
public int LedLen
{
get { return Led.Length/3; }
}
UdpClient udp;
byte sendIdx = 0;
public UnitData(string _host, int len)
{
Init(_host, len);
}
public void Init(string _host, int len)
{
Led = new byte[len * 3];
Host = _host;
Debug.Log(Host);
udp = new UdpClient();
udp.Connect(Host, 13531);
SetOffset(300);
SetMaxDelay(150);
}
public void SetColor(int index, byte r, byte g, byte b)
{
Led[index * 3] = g;
Led[index * 3 + 1] = r;
Led[index * 3 + 2] = b;
}
public void SetColor(int index,Color32 col)
{
SetColor(index, col.r, col.g, col.b);
}
private void send1(byte[] data, int len, int startPos)
{
// Debug.Log("send"+len.ToString());
byte[] d = new byte[5 + len * 3];
d[0] = sendIdx;
int ms = (int)(Time.realtimeSinceStartup * 1000) % 65536;
d[1] = (byte)(ms / 256);
d[2] = (byte)(ms % 256);
d[3] = (byte)(startPos / 8);
d[4] = (byte)(len / 2);
System.Array.Copy(data, startPos * 3, d, 5, len*3);
udp.Send(d, d.Length);
}
private void SendCommand(byte[] data, byte commandNo)
{
byte[] d = new byte[5 + data.Length];
d[0] = sendIdx;
int ms = (int)(Time.realtimeSinceStartup * 1000) % 65536;
d[1] = (byte)(ms / 256);
d[2] = (byte)(ms % 256);
d[3] = commandNo;
d[4] = 0;
System.Array.Copy(data, 0, d, 5, data.Length);
udp.Send(d, d.Length);
sendIdx++;
}
public void SetOffset(int offset)
{
SendCommand(new byte[] { (byte)(offset / 256), (byte)(offset % 256) }, 0);
}
public void SetMaxDelay(int delay)
{
SendCommand(new byte[] { (byte)(delay / 256), (byte)(delay % 256) }, 1);
}
public void Send()
{
int dataLen = Led.Length / 3;
int chunkMax = ((1472 - 6) / 3 / 8) * 8;
for (int j = 0; j < 1; j++)
{
for (int i = 0; i < dataLen; i += chunkMax)
{
int chunkLen = dataLen - i;
if (chunkMax < chunkLen) chunkLen = chunkMax;
send1(Led, chunkLen, i);
}
}
sendIdx++;
}
}
public class Led
{
public Vector2 Pos;
public Vector2 relPos;
GameObject Obj;
UnitData Unit;
Material Material;
int Index;
public float Level;
public Led(UnitData unit, int index, Vector2 pos, GameObject LedObj,float _level)
{
Init(unit, index, pos, LedObj,_level);
}
public void Init(UnitData unit, int index, Vector2 pos, GameObject LedObj,float level)
{
Unit = unit;
Obj = LedObj;
Level = level;
Material = Obj.GetComponent<Renderer>().material;
Pos = pos;
Index = index;
}
public void SetColor(Color32 col)
{
Unit.SetColor(Index, col.r , col.g ,col.b );
Material.SetColor("_EmissionColor", col);
}
public Color32 GetColor()
{
return Material.GetColor("_EmissionColor");
}
}
public class Setting : MonoBehaviour
{
public GameObject prefLED;
Data data;
// Use this for initialization
UnitData[] Units = { };
List<Led> Leds = new List<Led>();
public float timeSpan = 1 / 15.0f;
float delta;
Vector2 PosMax = new Vector2(-1e+10f, -1e+10f);
Vector2 PosMin = new Vector2(1e+10f, 1e+10f);
Vector2 PosCenter = new Vector2();
Vector2 PosSize = new Vector2();
bool Ready = false;
Igniter igniter;
void FillDummyLED()
{
Units = new UnitData[4];
float width = 11;
float height = 7;
for (int i=0;i<Units.Length;i++)
{
Units[i] = new UnitData("127.0.0.1", 1250);
//LED unit layout
//====== ========
//==1== ====2===
//0===== =======0
//
//0===== =======0
//==3== ====3===
//====== ========
for (int j = 0; j < 1250; j++)
{
float y = (j / 50 ) /24.0f;
float x = (j % 50 ) /49.0f;
if ((j / 50) % 2 == 0) x = 1 - x;
x *= width / 2;
y *= height / 2;
Vector3 pos = new Vector3();
switch (i)
{
case 0:
pos.x = -x - 0.15f/2;
pos.z = y + 0.1f/2;
break;
case 1:
pos.x = x + 0.15f/2;
pos.z = y + 0.1f/2;
break;
case 2:
pos.x = -x - 0.15f/2;
pos.z = -y - 0.1f/2;
break;
default:
pos.x = x + 0.15f/2;
pos.z = -y - 0.1f/2;
break;
}
pos.x += Random.Range(-0.1f, 0.1f);
pos.z += Random.Range(-0.1f, 0.1f);
GameObject o = Instantiate(prefLED);
o.transform.parent = this.transform;
o.transform.localPosition = pos;
Vector2 pos2 = new Vector2(pos.x, pos.z);
Leds.Add(new Led(Units[i], j, pos2, o,1));
}
}
}
private void UpdateRelPos()
{
foreach(Led led in Leds)
{
if (led.Level < Posthresh) continue;
Vector2 pos2 = led.Pos;
PosMax = Vector2.Max(PosMax, pos2);
PosMin = Vector2.Min(PosMin, pos2);
}
PosCenter = (PosMax + PosMin) / 2;
PosSize = (PosMax - PosMin) / 2;
{//to keep aspect TODO:is it needed???
if (PosSize.x > PosSize.y) PosSize.y = PosSize.x;
else PosSize.x = PosSize.y;
}
foreach (Led led in Leds)
{
led.relPos = (led.Pos - PosCenter) / PosSize;
}
}
public string Url = "http://127.0.0.1:8000/pos.json";
public float Registthresh = 0.01f;
public float Posthresh = 0.1f;
IEnumerator GetFromWWW()
{
WWW www = new WWW(Url);
while (!www.isDone)
{ // ダウンロードの進捗を表示
//print(Mathf.CeilToInt(www.progress * 100));
yield return null;
}
if (!string.IsNullOrEmpty(www.error))
{ // ダウンロードでエラーが発生した
print(www.error);
FillDummyLED();
UpdateRelPos();
Ready = true;
}
else
{ // ダウンロードが正常に完了し
//print(JsonUtility.ToJson(new Data()));
data = JsonConvert.DeserializeObject<Data>(www.text, Converter.Settings);
Units = new UnitData[data.Pos.Length];
for (int i = 0; i < data.Pos.Length; i++)
{
Units[i] = new UnitData(data.Host[i], data.Pos[i].Length);
for (int j = 0; j < data.Pos[i].Length; j++)
{
if (data.Level[i][j] < Registthresh) continue;
Vector3 pos = new Vector3(data.Pos[i][j][0], data.Pos[i][j][2] * 0, data.Pos[i][j][1]);
GameObject o = Instantiate(prefLED);
//o.SetActive(false);
o.transform.parent = this.transform;
o.transform.localPosition = pos;
Vector2 pos2 = new Vector2(pos.x, pos.z);
Leds.Add(new Led(Units[i], j, pos2, o,data.Level[i][j]));
}
}
UpdateRelPos();
Ready = true;
}
}
IEnumerator ShowLedObj;
void Start()
{
Ready = false;
StartCoroutine(GetFromWWW());
delta = 0;
stopFlag = true;
ShowLedObj = ShowLed();
igniter = new Igniter("192.168.10.35");
}
// Update is called once per frame
void Update()
{
}
int fixedCount = 0;
private void FixedUpdate()
{
if (Ready != true) return;
fixedCount++;
if (fixedCount > 3)
{
fixedCount = 0;
ShowLedObj.MoveNext();
foreach (UnitData unit in Units)
{
unit.Send();
}
}
/*
delta += Time.deltaTime;
if (delta > timeSpan)
{
//while (delta > timeSpan)
delta -= timeSpan;
ShowLedObj.MoveNext();
foreach (UnitData unit in Units)
{
unit.Send();
}
Igniter.Send();
}*/
}
float Bell(float p)
{
if (p < 0) p *= -1;
if (p > 1) return 0;
return 0.5f + 0.5f * Mathf.Cos(p * Mathf.PI);
}
float Wave(float p)
{
return 0.5f + 0.5f * Mathf.Sin(p * 2 * Mathf.PI);
}
void PhaseWave(float phase)
{
foreach (Led led in Leds)
{
float l = led.relPos.magnitude;
float a = Mathf.Atan2(led.relPos.y, led.relPos.x);
float v = Wave(l * 3 - phase * 30);
v *= Bell(3* l / (1 + phase * 4));
//v *= Wave(l * 0.5f + a + phase * 6);
v = Mathf.Pow(v, 1/3f);
float h = 0.95f;
float s = 1.0f;
//v *= phase;
//v = v *(1.0f-phase/2)+1.0f*phase/2;
//v *= 0.5f;
led.SetColor(Color.HSVToRGB(h, s, v));
}
}
void AddRand()
{
foreach (Led led in Leds)
{
Color32 c = led.GetColor();
if (c.r + c.g + c.b < 20)
{
float v = Random.Range(0, 0.02f);
float h = Random.Range(0, 1);
float s = 1.0f;
led.SetColor(c+ Color.HSVToRGB(h, s, v));
}
}
}
void PhaseIdle()
{
foreach (Led led in Leds)
{
float v = Random.Range(0f, 0.02f);
float h = Random.Range(0f,1f);
float s = 1.0f;
led.SetColor(Color.HSVToRGB(h, s, v));
}
}
public VideoToLed video1;
public VideoToLed video2;
float phase = 0;
bool stopFlag = true;
bool breakFlag = false;
IEnumerator ShowLed()
{
while (true)
{
video1.VideoPrepare(0);
video2.VideoPrepare(0);
video2.SetLoop(true);
while (stopFlag)
{
PhaseIdle();
yield return null;
}
breakFlag = false;
stopFlag = true;
//Ignite!!!!!!!!!!
for (int i=0;i<60;i++)
{
if (i < 2) igniter.Send(1);
PhaseIdle();
yield return null;
}
//Opening
while (!video1.IsReady())yield return null;
video1.VideoPlay();
while (!breakFlag)
{
float pos = video1.SetLed(Leds);
yield return null;
if (pos > 0.99f) break;
}
///Play
video1.VideoPause();
video2.VideoPlay();
while (!breakFlag)
{
float pos = video2.SetLed(Leds);
yield return null;
}
}
}
public void KickStart()
{
stopFlag = false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment