Sleep 20 ms each frame in the ambient mode
[kaka/cakelight.git] / src / kaka / cakelight / AmbientMode.java
1 package kaka.cakelight;
2
3 import kaka.cakelight.util.SimplexNoise3D;
4
5 public class AmbientMode extends Mode { // TODO split into DynamicAmbient and StaticAmbient?
6     private Thread thread; // TODO move to a dynamic sub class
7     private Configuration config;
8     private int type = 0;
9
10     public AmbientMode(String[] args) {
11         if (args.length > 0) {
12             type = Integer.parseInt(args[0]);
13         }
14     }
15
16     @Override
17     public void enter(Configuration config) {
18         this.config = config;
19         startThread();
20     }
21
22     @Override
23     public void exit() {
24         stopThread();
25     }
26
27     public void startThread() {
28         thread = new Thread() {
29             public void run() {
30                 try {
31                     long start = System.currentTimeMillis();
32                     int index = 0;
33                     while (!isInterrupted()) {
34                         LedFrame frame = LedFrame.from(config);
35                         updateFrame(frame, System.currentTimeMillis() - start, index);
36                         updateWithFrame(frame);
37                         index = (index + 1) % config.leds.getCount();
38                         Thread.sleep(20);
39                     }
40                 } catch (InterruptedException e) {
41                 }
42             }
43         };
44         thread.start();
45     }
46
47     public void stopThread() {
48         thread.interrupt();
49     }
50
51     /**
52      * @param frame
53      * @param time  Time in milliseconds since start
54      * @param count Goes from 0 to number of LEDs - 1
55      */
56     private void updateFrame(LedFrame frame, long time, int count) {
57         if (type == 0) {
58             for (int i = 0; i < config.leds.getCount(); i++) {
59                 double r = Math.sin(2 * i * Math.PI / config.leds.getCount() + time * 0.001) * 0.5 + 0.5;
60                 double g = Math.cos(2 * i * Math.PI / config.leds.getCount() + time * 0.002) * 0.5 + 0.5;
61                 frame.setLedColor(i, Color.rgb(r, g, 0));
62             }
63         } else if (type == 1) {
64             for (int i = 0; i < config.leds.getCount(); i++) {
65                 double x = frame.xOf(i);
66                 double y = frame.yOf(i);
67                 double g = Math.min(1, Math.max(0, noise.getr(-0.5, 0.5, 0.5, x, y, time / 5000.0)));
68                 double b = Math.pow(Math.min(1, Math.max(0, noise.getr(0, 0.9, 1, x, y, time / 7000.0))), 2);
69                 frame.setLedColor(i, Color.rgb(0, g, b));
70             }
71         } else if (type == 2) {
72             int ledCount = config.leds.getCount();
73             double hueOffset = time * 0.00001;
74             double hueLength = 1.0 / 6;
75             for (int i = 0; i < config.leds.getCount(); i++) {
76                 double ledOffset = (i + (hueOffset * ledCount)) % ledCount;
77                 double value = Math.abs((ledOffset * 2 - ledCount) / ledCount); // 1 to 0 to 1
78                 frame.setLedColor(i, Color.hsv(value * hueLength + hueOffset, 1, 1));
79             }
80         }
81     }
82
83     private SimplexNoise3D noise = new SimplexNoise3D(0);
84 }