Created
October 29, 2018 22:31
-
-
Save akirayou/91e2935ed2b58c463b7f5e6c63c55e65 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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