Created
October 12, 2018 08:45
-
-
Save akirayou/a3aec4b2252d71b0861afcbf8983d820 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 UnitData | |
{ | |
string Host; | |
byte[] Led; | |
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(200); | |
SetMaxDelay(100); | |
} | |
public void SetColor(int index, byte r, byte g, byte b) | |
{ | |
Led[index * 3] = r; | |
Led[index * 3 + 1] = g; | |
Led[index * 3 + 2] = 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.fixedTime * 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); | |
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.fixedTime * 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 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 Led(UnitData unit, int index, Vector2 pos, GameObject LedObj) | |
{ | |
Init(unit, index, pos, LedObj); | |
} | |
public void Init(UnitData unit, int index, Vector2 pos, GameObject LedObj) | |
{ | |
Unit = unit; | |
Obj = LedObj; | |
Material = Obj.GetComponent<Renderer>().material; | |
Pos = pos; | |
Index = index; | |
} | |
public void SetColor(Color32 col) | |
{ | |
Unit.SetColor(Index, (byte)(col.r * 255), (byte)(col.g * 255), (byte)(col.b * 255)); | |
Material.SetColor("_EmissionColor", col); | |
} | |
} | |
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(); | |
IEnumerator GetFromWWW() | |
{ | |
WWW www = new WWW("http://127.0.0.1:8000/pos.json"); | |
while (!www.isDone) | |
{ // ダウンロードの進捗を表示 | |
//print(Mathf.CeilToInt(www.progress * 100)); | |
yield return null; | |
} | |
if (!string.IsNullOrEmpty(www.error)) | |
{ // ダウンロードでエラーが発生した | |
print(www.error); | |
} | |
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] < 0.5) 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.transform.position = pos; | |
Vector2 pos2 = new Vector2(pos.x, pos.z); | |
PosMax = Vector2.Max(PosMax, pos2); | |
PosMin = Vector2.Min(PosMin, pos2); | |
Leds.Add(new Led(Units[i], j, pos2, o)); | |
} | |
} | |
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; | |
} | |
} | |
} | |
IEnumerator ShowLedObj; | |
void Start() | |
{ | |
StartCoroutine(GetFromWWW()); | |
delta = 0; | |
ShowLedObj = ShowLed(); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
delta += Time.deltaTime; | |
if (delta > timeSpan) | |
{ | |
while (delta > timeSpan) delta -= timeSpan; | |
ShowLedObj.MoveNext(); | |
foreach (UnitData unit in Units) | |
{ | |
unit.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 * 6 - phase * 10); | |
v *= Bell( 10*l / (1+phase*4) ); | |
v *= Wave(l*0.5f + a + phase * 6); | |
v = Mathf.Pow(v, 0.333f); | |
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)); | |
} | |
} | |
float phase = 0; | |
IEnumerator ShowLed() | |
{ | |
while (true) | |
{ | |
for (phase = 0; phase < 1; phase += 0.01f) | |
{ | |
PhaseWave(phase); | |
yield return null; | |
} | |
for (phase = 0; phase < 1; phase += 0.01f) | |
{ | |
PhaseWave(phase); | |
yield return null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment