├── By_grad.png ├── FRequency.xcf ├── FRequency_grad.png ├── LICENSE ├── README ├── SynRJ_grad.png ├── Title_grad.png ├── conf ├── FRQMusicEvents.h ├── Title.png ├── Title_grad.png ├── assets │ ├── fonts │ │ └── leaguegothic │ │ │ └── league_gothic-webfont.ttf │ └── images │ │ └── breakdom.jpg ├── buffers.jpg ├── conf_0.png ├── css │ ├── main.css │ └── reset.css ├── index.html ├── js │ └── slideshow.js ├── license ├── pixels.jpg ├── qr.png ├── script.png └── udav.png ├── dist.png ├── equa2_grad.png ├── equa_grad.png ├── gradient.png ├── index.html ├── js ├── bezier.js ├── camera.js ├── defuscate.js ├── main.js ├── osg-debug.js ├── osg.js ├── particles.js ├── path.js ├── text.js ├── time.js ├── timefunction.js ├── timeline.js └── ui.js ├── model0.png ├── model1.png ├── model2.png ├── model3.png ├── model4.png ├── model5.png ├── model6.png ├── point.png ├── replay.png ├── spinner.gif ├── style.css ├── texture_1024_1024.png ├── texture_1024_512.png ├── texture_512_512.png ├── tool ├── FRQ_converter.sh └── gradient.sh ├── twitter.png └── zik.ogg /By_grad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/By_grad.png -------------------------------------------------------------------------------- /FRequency.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/FRequency.xcf -------------------------------------------------------------------------------- /FRequency_grad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/FRequency_grad.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | AGPL for the code 2 | Data are copyrighted by their respective artists -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | demo: http://plopbyte.com/demojs-fff/ 2 | credits: http://plopbyte.com/demojs-fff/#credits 3 | 4 | tool used: 5 | gnuplot 6 | mathgl/udav 7 | octave 8 | distancemapgenerator https://github.com/cedricpinson/DistanceMapGenerator 9 | timeline.js https://github.com/cedricpinson/timeline.js 10 | osgjs https://github.com/cedricpinson/osgjs 11 | 12 | -------------------------------------------------------------------------------- /SynRJ_grad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/SynRJ_grad.png -------------------------------------------------------------------------------- /Title_grad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/Title_grad.png -------------------------------------------------------------------------------- /conf/FRQMusicEvents.h: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------------------------------- 2 | // This file was generated automatically from the FRequency VST Midi Event Mapper. Do not edit or modify 3 | // Generated date 28/06/2011 00:55:22 4 | // ----------------------------------------------------------------------------------------------------- 5 | #ifndef FRQMUSIC_EVENT_H 6 | #define FRQMUSIC_EVENT_H 7 | #include "EventManager.h" 8 | enum FRQMusicEventCode { 9 | FRQMusicNone = 0, 10 | FRQMusicKick = 1, 11 | FRQMusicSnare = 2, 12 | FRQMusicRiff = 3, 13 | FRQMusicChangePattern = 4, 14 | FRQMusicSound1 = 5, 15 | FRQMusicSound2 = 6, 16 | FRQMusicSound3 = 7, 17 | FRQMusicVocal = 8, 18 | FRQMusicSynth = 9 19 | }; 20 | 21 | static FRQ::BasicEventItem FRQMusicEventData[324] = { 22 | 161, 23 | 0x000E, 0x7F03, // Time 00:00.014 - Note F0 - Map to FRQMusicRiff 24 | 0x0001, 0x7F05, // Time 00:00.015 - Note A0 - Map to FRQMusicSound1 25 | 0x0389, 0x7F06, // Time 00:00.920 - Note B0 - Map to FRQMusicSound2 26 | 0x0399, 0x7F07, // Time 00:01.841 - Note C1 - Map to FRQMusicSound3 27 | 0x0739, 0x7F05, // Time 00:03.690 - Note A0 - Map to FRQMusicSound1 28 | 0x0398, 0x7F06, // Time 00:04.610 - Note B0 - Map to FRQMusicSound2 29 | 0x03A2, 0x7F07, // Time 00:05.540 - Note C1 - Map to FRQMusicSound3 30 | 0x0730, 0x7F04, // Time 00:07.380 - Note G0 - Map to FRQMusicChangePattern 31 | 0x0011, 0x7F03, // Time 00:07.397 - Note F0 - Map to FRQMusicRiff 32 | 0x0014, 0x7F05, // Time 00:07.417 - Note A0 - Map to FRQMusicSound1 33 | 0x0375, 0x7F06, // Time 00:08.302 - Note B0 - Map to FRQMusicSound2 34 | 0x0397, 0x7F07, // Time 00:09.221 - Note C1 - Map to FRQMusicSound3 35 | 0x0739, 0x7F03, // Time 00:11.070 - Note F0 - Map to FRQMusicRiff 36 | 0x0006, 0x7F05, // Time 00:11.076 - Note A0 - Map to FRQMusicSound1 37 | 0x039C, 0x7F06, // Time 00:12.000 - Note B0 - Map to FRQMusicSound2 38 | 0x0399, 0x7F07, // Time 00:12.921 - Note C1 - Map to FRQMusicSound3 39 | 0x0733, 0x7F04, // Time 00:14.764 - Note G0 - Map to FRQMusicChangePattern 40 | 0x0001, 0x7F01, // Time 00:14.765 - Note D0 - Map to FRQMusicKick 41 | 0x0000, 0x7F03, // Time 00:14.765 - Note F0 - Map to FRQMusicRiff 42 | 0x0000, 0x7F05, // Time 00:14.765 - Note A0 - Map to FRQMusicSound1 43 | 0x01CA, 0x7F02, // Time 00:15.223 - Note E0 - Map to FRQMusicSnare 44 | 0x01D4, 0x7F01, // Time 00:15.691 - Note D0 - Map to FRQMusicKick 45 | 0x000E, 0x7F06, // Time 00:15.705 - Note B0 - Map to FRQMusicSound2 46 | 0x01BE, 0x7F02, // Time 00:16.151 - Note E0 - Map to FRQMusicSnare 47 | 0x01CC, 0x7F01, // Time 00:16.611 - Note D0 - Map to FRQMusicKick 48 | 0x000F, 0x7F07, // Time 00:16.626 - Note C1 - Map to FRQMusicSound3 49 | 0x01BD, 0x7F02, // Time 00:17.071 - Note E0 - Map to FRQMusicSnare 50 | 0x01D8, 0x7F01, // Time 00:17.543 - Note D0 - Map to FRQMusicKick 51 | 0x01CC, 0x7F02, // Time 00:18.003 - Note E0 - Map to FRQMusicSnare 52 | 0x01CC, 0x7F01, // Time 00:18.463 - Note D0 - Map to FRQMusicKick 53 | 0x0004, 0x7F03, // Time 00:18.467 - Note F0 - Map to FRQMusicRiff 54 | 0x0014, 0x7F05, // Time 00:18.487 - Note A0 - Map to FRQMusicSound1 55 | 0x01B4, 0x7F02, // Time 00:18.923 - Note E0 - Map to FRQMusicSnare 56 | 0x01CC, 0x7F01, // Time 00:19.383 - Note D0 - Map to FRQMusicKick 57 | 0x0004, 0x7F06, // Time 00:19.387 - Note B0 - Map to FRQMusicSound2 58 | 0x01CB, 0x7F02, // Time 00:19.846 - Note E0 - Map to FRQMusicSnare 59 | 0x01CC, 0x7F01, // Time 00:20.306 - Note D0 - Map to FRQMusicKick 60 | 0x0002, 0x7F07, // Time 00:20.308 - Note C1 - Map to FRQMusicSound3 61 | 0x01CA, 0x7F02, // Time 00:20.766 - Note E0 - Map to FRQMusicSnare 62 | 0x01CC, 0x7F01, // Time 00:21.226 - Note D0 - Map to FRQMusicKick 63 | 0x01D4, 0x7F02, // Time 00:21.694 - Note E0 - Map to FRQMusicSnare 64 | 0x01CC, 0x7F04, // Time 00:22.154 - Note G0 - Map to FRQMusicChangePattern 65 | 0x0010, 0x7F01, // Time 00:22.170 - Note D0 - Map to FRQMusicKick 66 | 0x0001, 0x7F03, // Time 00:22.171 - Note F0 - Map to FRQMusicRiff 67 | 0x0001, 0x7F05, // Time 00:22.172 - Note A0 - Map to FRQMusicSound1 68 | 0x01BA, 0x7F02, // Time 00:22.614 - Note E0 - Map to FRQMusicSnare 69 | 0x000F, 0x7F09, // Time 00:22.629 - Note E1 - Map to FRQMusicSynth 70 | 0x01BD, 0x7F01, // Time 00:23.074 - Note D0 - Map to FRQMusicKick 71 | 0x000F, 0x7F06, // Time 00:23.089 - Note B0 - Map to FRQMusicSound2 72 | 0x00D9, 0x7F09, // Time 00:23.306 - Note E1 - Map to FRQMusicSynth 73 | 0x0076, 0x7F01, // Time 00:23.424 - Note D0 - Map to FRQMusicKick 74 | 0x0078, 0x7F02, // Time 00:23.544 - Note E0 - Map to FRQMusicSnare 75 | 0x01CC, 0x7F01, // Time 00:24.004 - Note D0 - Map to FRQMusicKick 76 | 0x0005, 0x7F07, // Time 00:24.009 - Note C1 - Map to FRQMusicSound3 77 | 0x01C7, 0x7F02, // Time 00:24.464 - Note E0 - Map to FRQMusicSnare 78 | 0x01CC, 0x7F01, // Time 00:24.924 - Note D0 - Map to FRQMusicKick 79 | 0x01CC, 0x7F02, // Time 00:25.384 - Note E0 - Map to FRQMusicSnare 80 | 0x01CE, 0x7F01, // Time 00:25.846 - Note D0 - Map to FRQMusicKick 81 | 0x0003, 0x7F03, // Time 00:25.849 - Note F0 - Map to FRQMusicRiff 82 | 0x0001, 0x7F05, // Time 00:25.850 - Note A0 - Map to FRQMusicSound1 83 | 0x01C8, 0x7F02, // Time 00:26.306 - Note E0 - Map to FRQMusicSnare 84 | 0x0003, 0x7F09, // Time 00:26.309 - Note E1 - Map to FRQMusicSynth 85 | 0x01C9, 0x7F01, // Time 00:26.766 - Note D0 - Map to FRQMusicKick 86 | 0x0003, 0x7F06, // Time 00:26.769 - Note B0 - Map to FRQMusicSound2 87 | 0x00EB, 0x7F09, // Time 00:27.004 - Note E1 - Map to FRQMusicSynth 88 | 0x00DE, 0x7F02, // Time 00:27.226 - Note E0 - Map to FRQMusicSnare 89 | 0x01D4, 0x7F01, // Time 00:27.694 - Note D0 - Map to FRQMusicKick 90 | 0x000F, 0x7F07, // Time 00:27.709 - Note C1 - Map to FRQMusicSound3 91 | 0x01BD, 0x7F02, // Time 00:28.154 - Note E0 - Map to FRQMusicSnare 92 | 0x01CC, 0x7F01, // Time 00:28.614 - Note D0 - Map to FRQMusicKick 93 | 0x01CB, 0x7F02, // Time 00:29.073 - Note E0 - Map to FRQMusicSnare 94 | 0x0011, 0x7F09, // Time 00:29.090 - Note E1 - Map to FRQMusicSynth 95 | 0x01BF, 0x7F04, // Time 00:29.537 - Note G0 - Map to FRQMusicChangePattern 96 | 0x0013, 0x7F01, // Time 00:29.556 - Note D0 - Map to FRQMusicKick 97 | 0x0015, 0x7F03, // Time 00:29.577 - Note F0 - Map to FRQMusicRiff 98 | 0x0000, 0x7F08, // Time 00:29.577 - Note D1 - Map to FRQMusicVocal 99 | 0x0015, 0x7F09, // Time 00:29.598 - Note E1 - Map to FRQMusicSynth 100 | 0x00A7, 0x7F01, // Time 00:29.765 - Note D0 - Map to FRQMusicKick 101 | 0x00EB, 0x7F02, // Time 00:30.000 - Note E0 - Map to FRQMusicSnare 102 | 0x00E2, 0x7F01, // Time 00:30.226 - Note D0 - Map to FRQMusicKick 103 | 0x00EC, 0x7F01, // Time 00:30.462 - Note D0 - Map to FRQMusicKick 104 | 0x000E, 0x7F08, // Time 00:30.476 - Note D1 - Map to FRQMusicVocal 105 | 0x01BB, 0x7F02, // Time 00:30.919 - Note E0 - Map to FRQMusicSnare 106 | 0x01CB, 0x7F01, // Time 00:31.378 - Note D0 - Map to FRQMusicKick 107 | 0x000E, 0x7F08, // Time 00:31.392 - Note D1 - Map to FRQMusicVocal 108 | 0x0001, 0x7F09, // Time 00:31.393 - Note E1 - Map to FRQMusicSynth 109 | 0x01C6, 0x7F02, // Time 00:31.847 - Note E0 - Map to FRQMusicSnare 110 | 0x00E2, 0x7F08, // Time 00:32.073 - Note D1 - Map to FRQMusicVocal 111 | 0x00EA, 0x7F01, // Time 00:32.307 - Note D0 - Map to FRQMusicKick 112 | 0x01C2, 0x7F02, // Time 00:32.757 - Note E0 - Map to FRQMusicSnare 113 | 0x01CC, 0x7F01, // Time 00:33.217 - Note D0 - Map to FRQMusicKick 114 | 0x000D, 0x7F03, // Time 00:33.230 - Note F0 - Map to FRQMusicRiff 115 | 0x01C7, 0x7F02, // Time 00:33.685 - Note E0 - Map to FRQMusicSnare 116 | 0x01CC, 0x7F01, // Time 00:34.145 - Note D0 - Map to FRQMusicKick 117 | 0x0005, 0x7F08, // Time 00:34.150 - Note D1 - Map to FRQMusicVocal 118 | 0x01C7, 0x7F02, // Time 00:34.605 - Note E0 - Map to FRQMusicSnare 119 | 0x0004, 0x7F09, // Time 00:34.609 - Note E1 - Map to FRQMusicSynth 120 | 0x01C8, 0x7F01, // Time 00:35.065 - Note D0 - Map to FRQMusicKick 121 | 0x0005, 0x7F09, // Time 00:35.070 - Note E1 - Map to FRQMusicSynth 122 | 0x01D1, 0x7F02, // Time 00:35.535 - Note E0 - Map to FRQMusicSnare 123 | 0x01CC, 0x7F01, // Time 00:35.995 - Note D0 - Map to FRQMusicKick 124 | 0x01CC, 0x7F02, // Time 00:36.455 - Note E0 - Map to FRQMusicSnare 125 | 0x01CC, 0x7F04, // Time 00:36.915 - Note G0 - Map to FRQMusicChangePattern 126 | 0x0010, 0x7F01, // Time 00:36.931 - Note D0 - Map to FRQMusicKick 127 | 0x0000, 0x7F09, // Time 00:36.931 - Note E1 - Map to FRQMusicSynth 128 | 0x01BC, 0x7F02, // Time 00:37.375 - Note E0 - Map to FRQMusicSnare 129 | 0x00E6, 0x7F09, // Time 00:37.605 - Note E1 - Map to FRQMusicSynth 130 | 0x00E8, 0x7F01, // Time 00:37.837 - Note D0 - Map to FRQMusicKick 131 | 0x01CC, 0x7F02, // Time 00:38.297 - Note E0 - Map to FRQMusicSnare 132 | 0x01CC, 0x7F01, // Time 00:38.757 - Note D0 - Map to FRQMusicKick 133 | 0x000D, 0x7F09, // Time 00:38.770 - Note E1 - Map to FRQMusicSynth 134 | 0x01BF, 0x7F02, // Time 00:39.217 - Note E0 - Map to FRQMusicSnare 135 | 0x01DE, 0x7F01, // Time 00:39.695 - Note D0 - Map to FRQMusicKick 136 | 0x01CC, 0x7F02, // Time 00:40.155 - Note E0 - Map to FRQMusicSnare 137 | 0x000F, 0x7F09, // Time 00:40.170 - Note E1 - Map to FRQMusicSynth 138 | 0x0145, 0x7F02, // Time 00:40.495 - Note E0 - Map to FRQMusicSnare 139 | 0x006E, 0x7F01, // Time 00:40.605 - Note D0 - Map to FRQMusicKick 140 | 0x0005, 0x7F09, // Time 00:40.610 - Note E1 - Map to FRQMusicSynth 141 | 0x01C7, 0x7F02, // Time 00:41.065 - Note E0 - Map to FRQMusicSnare 142 | 0x01D6, 0x7F01, // Time 00:41.535 - Note D0 - Map to FRQMusicKick 143 | 0x000F, 0x7F09, // Time 00:41.550 - Note E1 - Map to FRQMusicSynth 144 | 0x01BD, 0x7F02, // Time 00:41.995 - Note E0 - Map to FRQMusicSnare 145 | 0x01CC, 0x7F01, // Time 00:42.455 - Note D0 - Map to FRQMusicKick 146 | 0x000F, 0x7F09, // Time 00:42.470 - Note E1 - Map to FRQMusicSynth 147 | 0x01BD, 0x7F02, // Time 00:42.915 - Note E0 - Map to FRQMusicSnare 148 | 0x0156, 0x7F01, // Time 00:43.257 - Note D0 - Map to FRQMusicKick 149 | 0x015C, 0x7F01, // Time 00:43.605 - Note D0 - Map to FRQMusicKick 150 | 0x00E8, 0x7F02, // Time 00:43.837 - Note E0 - Map to FRQMusicSnare 151 | 0x00E4, 0x7F01, // Time 00:44.065 - Note D0 - Map to FRQMusicKick 152 | 0x00E8, 0x7F04, // Time 00:44.297 - Note G0 - Map to FRQMusicChangePattern 153 | 0x000E, 0x7F01, // Time 00:44.311 - Note D0 - Map to FRQMusicKick 154 | 0x0000, 0x7F09, // Time 00:44.311 - Note E1 - Map to FRQMusicSynth 155 | 0x01BF, 0x7F02, // Time 00:44.758 - Note E0 - Map to FRQMusicSnare 156 | 0x00EE, 0x7F09, // Time 00:44.996 - Note E1 - Map to FRQMusicSynth 157 | 0x00DE, 0x7F01, // Time 00:45.218 - Note D0 - Map to FRQMusicKick 158 | 0x015C, 0x7F01, // Time 00:45.566 - Note D0 - Map to FRQMusicKick 159 | 0x0078, 0x7F02, // Time 00:45.686 - Note E0 - Map to FRQMusicSnare 160 | 0x01CC, 0x7F01, // Time 00:46.146 - Note D0 - Map to FRQMusicKick 161 | 0x0004, 0x7F09, // Time 00:46.150 - Note E1 - Map to FRQMusicSynth 162 | 0x01C8, 0x7F02, // Time 00:46.606 - Note E0 - Map to FRQMusicSnare 163 | 0x01CD, 0x7F01, // Time 00:47.067 - Note D0 - Map to FRQMusicKick 164 | 0x01D8, 0x7F02, // Time 00:47.539 - Note E0 - Map to FRQMusicSnare 165 | 0x0001, 0x7F09, // Time 00:47.540 - Note E1 - Map to FRQMusicSynth 166 | 0x01CE, 0x7F01, // Time 00:48.002 - Note D0 - Map to FRQMusicKick 167 | 0x0006, 0x7F09, // Time 00:48.008 - Note E1 - Map to FRQMusicSynth 168 | 0x01C5, 0x7F02, // Time 00:48.461 - Note E0 - Map to FRQMusicSnare 169 | 0x01CD, 0x7F01, // Time 00:48.922 - Note D0 - Map to FRQMusicKick 170 | 0x000F, 0x7F09, // Time 00:48.937 - Note E1 - Map to FRQMusicSynth 171 | 0x01BD, 0x7F02, // Time 00:49.382 - Note E0 - Map to FRQMusicSnare 172 | 0x01CE, 0x7F01, // Time 00:49.844 - Note D0 - Map to FRQMusicKick 173 | 0x000B, 0x7F09, // Time 00:49.855 - Note E1 - Map to FRQMusicSynth 174 | 0x01C1, 0x7F02, // Time 00:50.304 - Note E0 - Map to FRQMusicSnare 175 | 0x01CC, 0x7F01, // Time 00:50.764 - Note D0 - Map to FRQMusicKick 176 | 0x01CC, 0x7F02, // Time 00:51.224 - Note E0 - Map to FRQMusicSnare 177 | 0x01D6, 0x7F04, // Time 00:51.694 - Note G0 - Map to FRQMusicChangePattern 178 | 0x0003, 0x7F01, // Time 00:51.697 - Note D0 - Map to FRQMusicKick 179 | 0x0014, 0x7F05, // Time 00:51.717 - Note A0 - Map to FRQMusicSound1 180 | 0x0014, 0x7F09, // Time 00:51.737 - Note E1 - Map to FRQMusicSynth 181 | 0x0199, 0x7F01, // Time 00:52.146 - Note D0 - Map to FRQMusicKick 182 | 0x000C, 0x7F02, // Time 00:52.158 - Note E0 - Map to FRQMusicSnare 183 | 0x01C0, 0x7F06, // Time 00:52.606 - Note B0 - Map to FRQMusicSound2 184 | 0x0000 // End of datas 185 | }; 186 | 187 | #endif 188 | -------------------------------------------------------------------------------- /conf/Title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/Title.png -------------------------------------------------------------------------------- /conf/Title_grad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/Title_grad.png -------------------------------------------------------------------------------- /conf/assets/fonts/leaguegothic/league_gothic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/assets/fonts/leaguegothic/league_gothic-webfont.ttf -------------------------------------------------------------------------------- /conf/assets/images/breakdom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/assets/images/breakdom.jpg -------------------------------------------------------------------------------- /conf/buffers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/buffers.jpg -------------------------------------------------------------------------------- /conf/conf_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/conf_0.png -------------------------------------------------------------------------------- /conf/css/main.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Hakim El Hattab 3 | */ 4 | 5 | 6 | /********************************************* 7 | * FONT-FACE DEFINITIONS 8 | *********************************************/ 9 | 10 | @font-face { 11 | font-family: 'League Gothic'; 12 | src: url('../assets/fonts/leaguegothic/league_gothic-webfont.ttf') format('truetype'); 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | 18 | /********************************************* 19 | * GLOBAL STYLES 20 | *********************************************/ 21 | 22 | html, body { 23 | padding: 0; 24 | margin: 0; 25 | overflow: hidden; 26 | 27 | font-family: 'Crimson Text', Times, 'Times New Roman', serif; 28 | font-size: 36px; 29 | 30 | background: #fff; 31 | color: #222; 32 | 33 | width: 100%; 34 | height: 100%; 35 | 36 | background-image: -webkit-gradient( 37 | radial, 38 | 50% 50%, 0, 39 | 50% 50%, 1000, 40 | from(rgba(245,245,245,1.0)), 41 | to(rgba(100,100,100,1.0)) 42 | ); 43 | 44 | background-image: -moz-radial-gradient( 45 | 50% 50% 90deg, 46 | rgba(245,245,245,1.0) 0%, 47 | rgba(100,100,100,1.0) 100% 48 | ); 49 | 50 | } 51 | 52 | 53 | /********************************************* 54 | * HEADERS 55 | *********************************************/ 56 | h1, h2, h3, h4 { 57 | margin: 0 0 20px 0; 58 | font-family: 'League Gothic', Arial, Helvetica, sans-serif; 59 | line-height: 0.9em; 60 | letter-spacing: 0.02em; 61 | text-transform: uppercase; 62 | color: #222; 63 | text-shadow: 0px 0px 2px #fff, 0px 0px 4px #bbb; 64 | } 65 | 66 | h1 { font-size: 136px; } 67 | h2 { font-size: 76px; } 68 | h3 { font-size: 56px; } 69 | h4 { font-size: 36px; } 70 | 71 | h1.inverted, 72 | h2.inverted, 73 | h3.inverted, 74 | h4.inverted { 75 | color: #fff; 76 | text-shadow: 0px 0px 2px #fff, 0px 0px 2px #888; 77 | } 78 | 79 | 80 | /********************************************* 81 | * SLIDES 82 | *********************************************/ 83 | #main { 84 | position: absolute; 85 | width: 800px; 86 | height: 600px; 87 | 88 | left: 50%; 89 | top: 50%; 90 | margin-left: -400px; 91 | margin-top: -320px; 92 | 93 | text-align: center; 94 | 95 | -webkit-perspective: 600px; 96 | -webkit-perspective-origin: 50% 25%; 97 | } 98 | 99 | #main>section, 100 | #main>section>section { 101 | display: none; 102 | 103 | position: absolute; 104 | width: 100%; 105 | min-height: 600px; 106 | 107 | -webkit-transform-style: preserve-3d; 108 | 109 | -webkit-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); 110 | -moz-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); 111 | -o-transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); 112 | transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985); 113 | } 114 | 115 | #main section.past { 116 | display: block; 117 | opacity: 0; 118 | 119 | -webkit-transform: translate3d(-100%, 0, 0) 120 | rotateY(-90deg) 121 | translate3d(-100%, 0, 0); 122 | } 123 | 124 | #main section.present { 125 | display: block; 126 | } 127 | 128 | #main section.future { 129 | display: block; 130 | opacity: 0; 131 | 132 | -webkit-transform: translate3d(100%, 0, 0) 133 | rotateY(90deg) 134 | translate3d(100%, 0, 0); 135 | } 136 | 137 | #main section>section.past { 138 | display: block; 139 | opacity: 0; 140 | 141 | -webkit-transform: translate3d(0, -50%, 0) 142 | rotateX(70deg) 143 | translate3d(0, -50%, 0); 144 | } 145 | #main section>section.future { 146 | display: block; 147 | opacity: 0; 148 | 149 | -webkit-transform: translate3d(0, 50%, 0) 150 | rotateX(-70deg) 151 | translate3d(0, 50%, 0); 152 | } 153 | 154 | 155 | /********************************************* 156 | * DEFAULT ELEMENT STYLES 157 | *********************************************/ 158 | 159 | #main>section { 160 | line-height: 1.2em; 161 | text-shadow: 0px 0px 2px #fff, 0px 0px 4px #bbb; 162 | font-weight: 600; 163 | } 164 | 165 | ol { 166 | list-style: decimal; 167 | list-style-position: inside; 168 | display: inline-block; 169 | text-align:left; 170 | } 171 | 172 | ul { 173 | list-style-position: inside; 174 | display: inline-block; 175 | text-align:left; 176 | } 177 | 178 | li, p { 179 | margin-top: 10px; 180 | margin-bottom: 10px; 181 | } 182 | 183 | a:not(.image) { 184 | color: #1b6263; 185 | text-decoration: none; 186 | border-bottom: 1px dashed rgba(0,0,0,0.3); 187 | padding: 1px 3px; 188 | } 189 | 190 | a:not(.image):hover { 191 | color: #fff; 192 | background: #2fa794; 193 | text-shadow: none; 194 | border: none; 195 | } 196 | 197 | img { 198 | margin: 30px 0 0 0; 199 | background: rgba(255,255,255,0.12); 200 | border: 4px solid #eee; 201 | 202 | -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); 203 | -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); 204 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); 205 | 206 | -webkit-transition: all .11s linear; 207 | -moz-transition: all .11s linear; 208 | -o-transition: all .11s linear; 209 | transition: all .11s linear; 210 | } 211 | 212 | a.image:hover img { 213 | background: rgba(255,255,255,0.2); 214 | 215 | -webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.25); 216 | -moz-box-shadow: 0 0 20px rgba(0, 0, 0, 0.25); 217 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.25); 218 | } 219 | -------------------------------------------------------------------------------- /conf/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } 49 | 50 | 51 | /* HTML5BP: 52 | These selection declarations have to be separate. 53 | No text-shadow: twitter.com/miketaylr/status/12228805301 54 | Also: hot pink. */ 55 | ::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; } 56 | ::selection { background:#FF5E99; color:#fff; text-shadow: none; } 57 | 58 | -------------------------------------------------------------------------------- /conf/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Inside FFF 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 |

Inside FFF

22 | 23 | 24 | 29 |
30 | 31 |
32 |

Invite Intro

33 |
    34 |
  1. Use to announce a demo party event
  2. 35 |
  3. 10 days
  4. 36 |
  5. Do something fun
  6. 37 |
38 |
39 | 40 | 41 |
42 |

Particles on GPU

43 |
    44 |
  1. Why on gpu ?
  2. 45 |
  3. Previous work - firefox, google
  4. 46 |
  5. Particles master - the beginning
  6. 47 |
48 |
49 | 50 |
51 |

How to move particles on gpu

52 |
    53 |
  1. 3 buffers 512x512 = 262k particles in 24 bits
  2. 54 |
  3. distance map 1, 2 fit shapes - generator/octave
  4. 55 |
  5. procedural velocity field - mathgl/udav
  6. 56 |
57 |
58 | 59 |
60 |

Music

61 |
    62 |
  1. Input pattern data
  2. 63 |
  3. Timeline.js sync events
  4. 64 |
65 |
66 | 67 |
68 |

Model 3D

69 |
    70 |
  1. Data exported from blender
  2. 71 |
  3. Convert 3D point to texture
  4. 72 |
73 |
74 | 75 |
76 |

Links

77 |
    78 |
  1. WebGL particles
  2. 79 |
  3. FRequency
  4. 80 |
  5. Credits
  6. 81 |
  7. Hakimel slideshow
  8. 82 |
83 |
84 | 85 |
86 |

Buffers

87 | 88 |
89 | 90 |
91 |

Pixels

92 | 93 |
94 | 95 |
96 |

Distance map

97 | 98 |
99 | 100 |
101 |

Gradient map

102 | 103 |
104 | 105 |
106 |

UDAV Script

107 | 108 |
109 | 110 |
111 |

UDAV

112 | 113 |
114 | 115 | 116 |
117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /conf/js/slideshow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2011 Hakim El Hattab, http://hakim.se 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | /** 24 | * Handles the very minimal navigation logic involved in the 25 | * slideshow. Including keyboard navigation, touch interaction 26 | * and URL history behavior. 27 | * 28 | * Slides are given unique hash based URL's so that they can be 29 | * opened directly. I didn't use the HTML5 History API for this 30 | * as it would have required the addition of server side rewrite 31 | * rules and hence require more effort for anyone to set up. 32 | * 33 | * This component can be called from other scripts via a tiny API: 34 | * - Slideshow.navigateTo( indexh, indexv ); 35 | * - Slideshow.navigateLeft(); 36 | * - Slideshow.navigateRight(); 37 | * - Slideshow.navigateUp(); 38 | * - Slideshow.navigateDown(); 39 | * 40 | * 41 | * version 0.1: 42 | * - First release 43 | * 44 | * version 0.2: 45 | * - Refactored code and added inline documentation 46 | * - Slides now have unique URL's 47 | * - A basic API to invoke navigation was added 48 | * 49 | * version 0.3: 50 | * - Added licensing terms 51 | * 52 | * 53 | * @author Hakim El Hattab 54 | * @version 0.3 55 | */ 56 | var Slideshow = (function(){ 57 | 58 | var indexh = 0, 59 | indexv = 0; 60 | 61 | /** 62 | * Activates the main program logic. 63 | */ 64 | function initialize() { 65 | document.addEventListener('keydown', onDocumentKeyDown, false); 66 | document.addEventListener('touchstart', onDocumentTouchStart, false); 67 | window.addEventListener('hashchange', onWindowHashChange, false); 68 | 69 | // Read the initial state of the URL (hash) 70 | readURL(); 71 | } 72 | 73 | /** 74 | * Handler for the document level 'keydown' event. 75 | * 76 | * @param {Object} event 77 | */ 78 | function onDocumentKeyDown( event ) { 79 | if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey || 80 | event.keyIdentifier === "Alt") 81 | return; 82 | 83 | if( event.keyCode >= 37 && event.keyCode <= 40 ) { 84 | 85 | switch( event.keyCode ) { 86 | case 37: navigateLeft(); break; // left 87 | case 39: navigateRight(); break; // right 88 | case 38: navigateUp(); break; // up 89 | case 40: navigateDown(); break; // down 90 | } 91 | 92 | slide(); 93 | 94 | event.preventDefault(); 95 | 96 | } 97 | } 98 | 99 | /** 100 | * Handler for the document level 'touchstart' event. 101 | * 102 | * This enables very basic tap interaction for touch 103 | * devices. Added mainly for performance testing of 3D 104 | * transforms on iOS but was so happily surprised with 105 | * how smoothly it runs so I left it in here. Apple +1 106 | * 107 | * @param {Object} event 108 | */ 109 | function onDocumentTouchStart( event ) { 110 | 111 | // We're only interested in one point taps 112 | if (event.touches.length == 1) { 113 | event.preventDefault(); 114 | 115 | var point = { 116 | x: event.touches[0].clientX, 117 | y: event.touches[0].clientY 118 | }; 119 | 120 | // Define the extent of the areas that may be tapped 121 | // to navigate 122 | var wt = window.innerWidth * 0.3; 123 | var ht = window.innerHeight * 0.3; 124 | 125 | if( point.x < wt ) { 126 | navigateLeft(); 127 | } 128 | else if( point.x > window.innerWidth - wt ) { 129 | navigateRight(); 130 | } 131 | else if( point.y < ht ) { 132 | navigateUp(); 133 | } 134 | else if( point.y > window.innerHeight - ht ) { 135 | navigateDown(); 136 | } 137 | 138 | slide(); 139 | 140 | } 141 | } 142 | 143 | 144 | /** 145 | * Handler for the window level 'hashchange' event. 146 | * 147 | * @param {Object} event 148 | */ 149 | function onWindowHashChange( event ) { 150 | readURL(); 151 | } 152 | 153 | /** 154 | * Updates one dimension of slides by showing the slide 155 | * with the specified index. 156 | * 157 | * @param {String} selector A CSS selector that will fetch 158 | * the group of slides we are working with 159 | * @param {Number} index The index of the slide that should be 160 | * shown 161 | * 162 | * @return {Number} The index of the slide that is now shown, 163 | * might differ from the passed in index if it was out of 164 | * bounds. 165 | */ 166 | function updateSlides( selector, index ) { 167 | 168 | // Select all slides and convert the NodeList result to 169 | // an array 170 | var slides = Array.prototype.slice.call( document.querySelectorAll( selector ) ); 171 | 172 | if( slides.length ) { 173 | // Enforce max and minimum index bounds 174 | index = Math.max(Math.min(index, slides.length - 1), 0); 175 | 176 | slides[index].setAttribute('class', 'present'); 177 | 178 | // Any element previous to index is given the 'past' class 179 | slides.slice(0, index).map(function(element){ 180 | element.setAttribute('class', 'past'); 181 | }); 182 | 183 | // Any element subsequent to index is given the 'future' class 184 | slides.slice(index + 1).map(function(element){ 185 | element.setAttribute('class', 'future'); 186 | }); 187 | } 188 | else { 189 | // Since there are no slides we can't be anywhere beyond the 190 | // zeroth index 191 | index = 0; 192 | } 193 | 194 | return index; 195 | 196 | } 197 | 198 | /** 199 | * Updates the visual slides to represent the currently 200 | * set indices. 201 | */ 202 | function slide() { 203 | indexh = updateSlides( '#main>section', indexh ); 204 | indexv = updateSlides( 'section.present>section', indexv ); 205 | 206 | writeURL(); 207 | } 208 | 209 | /** 210 | * Reads the current URL (hash) and navigates accordingly. 211 | */ 212 | function readURL() { 213 | // Break the hash down to separate components 214 | var bits = window.location.hash.slice(2).split('/'); 215 | 216 | // Read the index components of the hash 217 | indexh = bits[0] ? parseInt( bits[0] ) : 0; 218 | indexv = bits[1] ? parseInt( bits[1] ) : 0; 219 | 220 | navigateTo( indexh, indexv ); 221 | } 222 | 223 | /** 224 | * Updates the page URL (hash) to reflect the current 225 | * navigational state. 226 | */ 227 | function writeURL() { 228 | var url = '/'; 229 | 230 | // Only include the minimum possible number of components in 231 | // the URL 232 | if( indexh > 0 || indexv > 0 ) url += indexh 233 | if( indexv > 0 ) url += '/' + indexv 234 | 235 | window.location.hash = url; 236 | } 237 | 238 | /** 239 | * Triggers a navigation to the specified indices. 240 | * 241 | * @param {Number} h The horizontal index of the slide to show 242 | * @param {Number} v The vertical index of the slide to show 243 | */ 244 | function navigateTo( h, v ) { 245 | indexh = h === undefined ? indexh : h; 246 | indexv = v === undefined ? indexv : v; 247 | 248 | slide(); 249 | } 250 | 251 | function navigateLeft() { 252 | indexh --; 253 | indexv = 0; 254 | slide(); 255 | } 256 | function navigateRight() { 257 | indexh ++; 258 | indexv = 0; 259 | slide(); 260 | } 261 | function navigateUp() { 262 | indexv --; 263 | slide(); 264 | } 265 | function navigateDown() { 266 | indexv ++; 267 | slide(); 268 | } 269 | 270 | // Initialize the program. Done right before returning to ensure 271 | // that any inline variable definitions are available to all 272 | // functions 273 | initialize(); 274 | 275 | // Expose some methods publicly 276 | return { 277 | navigateTo: navigateTo, 278 | navigateLeft: navigateLeft, 279 | navigateRight: navigateRight, 280 | navigateUp: navigateUp, 281 | navigateDown: navigateDown 282 | }; 283 | 284 | })(); 285 | 286 | -------------------------------------------------------------------------------- /conf/license: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011 Hakim El Hattab, http://hakim.se 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /conf/pixels.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/pixels.jpg -------------------------------------------------------------------------------- /conf/qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/qr.png -------------------------------------------------------------------------------- /conf/script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/script.png -------------------------------------------------------------------------------- /conf/udav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/conf/udav.png -------------------------------------------------------------------------------- /dist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/dist.png -------------------------------------------------------------------------------- /equa2_grad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/equa2_grad.png -------------------------------------------------------------------------------- /equa_grad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/equa_grad.png -------------------------------------------------------------------------------- /gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/gradient.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | FFF
by
SynRJ and FRequency

22 | Loading, please wait... 23 | 24 |
25 |
26 |
27 |
28 |
29 | 33 |
34 | Replay demo 35 |
36 |
37 | 38 |
39 |
40 | 41 |
42 |

Credits

43 | 96 |
97 |

greetings

98 | 123 |
124 | 128 | 132 |
133 | 134 | 135 | -------------------------------------------------------------------------------- /js/bezier.js: -------------------------------------------------------------------------------- 1 | // dont know bezier look here http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/ 2 | 3 | 4 | var BezierPath = function() { 5 | this.keys = []; 6 | }; 7 | 8 | BezierPath.prototype = { 9 | getKeyIndexFromTime: function(keys, t) { 10 | var size = keys.length; 11 | if (size === 0) { 12 | osg.log("getKeyIndexFromTime the container is empty, impossible to get key index from time"); 13 | return -1; 14 | } 15 | 16 | for (var i = 0, l = size-1; i < l; i++) { 17 | var t0 = keys[i].t; 18 | var t1 = keys[i+1].t; 19 | if ( t >= t0 && t < t1 ) 20 | { 21 | this.lastKeyAccess = i; 22 | return i; 23 | } 24 | } 25 | }, 26 | 27 | calculateBezierPoint: function (t, p0, p1, p2, p3, result) { 28 | var u = 1-t; 29 | var tt = t*t; 30 | var uu = u*u; 31 | var uuu = uu * u; 32 | var ttt = tt * t; 33 | 34 | var p_0 = osg.Vec3.mult(p0, uuu, []); //first term 35 | var p_1 = osg.Vec3.mult(p1, 3 * uu * t, []); //second term 36 | var p_2 = osg.Vec3.mult(p2, 3 * u * tt, []); //third term 37 | var p_3 = osg.Vec3.mult(p3, ttt, []); //fourth term 38 | 39 | result[0] = p_0[0] + p_1[0] + p_2[0] + p_3[0]; 40 | result[1] = p_0[1] + p_1[1] + p_2[1] + p_3[1]; 41 | result[2] = p_0[2] + p_1[2] + p_2[2] + p_3[2]; 42 | return result; 43 | }, 44 | 45 | getValue: function(t, result) { 46 | return this._getValue(this.keys, t, result); 47 | }, 48 | _getValue: function(keys, t, result) { 49 | 50 | if (t >= keys[keys.length-1].t) { 51 | osg.Vec3.copy(keys[keys.length-1].value, result); 52 | return; 53 | } else if (t <= keys[0].t) { 54 | osg.Vec3.copy(keys[0].value, result); 55 | return; 56 | } 57 | 58 | var i = this.getKeyIndexFromTime(keys, t); 59 | var t0 = keys[i].t; 60 | var t1 = keys[i+1].t; 61 | var tf = (t - t0) / ( t1 - t0); 62 | 63 | return this.calculateBezierPoint(tf, keys[i].value, keys[i].cin, keys[i].cout, keys[i+1].value, result); 64 | }, 65 | 66 | addKey: function(t, p0, p1, p2) { 67 | this.keys.push({ t: t, 68 | cin: p1, 69 | value: p0, 70 | cout: p2}); 71 | }, 72 | 73 | 74 | computePath: function() { 75 | var points = []; 76 | 77 | for (var i = 0, l = this.keys.length-1; i < l; i++) { 78 | var p0 = this.keys[i].value; 79 | var p1 = this.keys[i].cin; 80 | var p2 = this.keys[i].cout; 81 | var p3 = this.keys[i+1].value; 82 | 83 | if(i == 0) //Only do this for the first endpoint. 84 | //When i != 0, this coincides with the end 85 | //point of the previous segment 86 | { 87 | points.push(this.calculateBezierPoint(0, p0, p1, p2, p3, [])); 88 | } 89 | 90 | var SEGMENTS_PER_CURVE = 10; 91 | for(var j = 1; j <= SEGMENTS_PER_CURVE; j++) 92 | { 93 | var t = j / SEGMENTS_PER_CURVE; 94 | points.push(this.calculateBezierPoint(t, p0, p1, p2, p3, [])); 95 | } 96 | } 97 | return points; 98 | } 99 | }; 100 | 101 | 102 | var createModelFromCurve = function(keysPosition, color) { 103 | var g = new osg.Geometry(); 104 | 105 | if (color === undefined) { 106 | color = [1.0, 1.0, 1.0, 0.7 ]; 107 | } 108 | 109 | var colors = []; 110 | var vertexes = []; 111 | for (var i = 0, l = keysPosition.length; i < l; i++) { 112 | vertexes.push(keysPosition[i][0], keysPosition[i][1], keysPosition[i][2]); 113 | } 114 | for (var i = 0, l = vertexes.length/3; i < l; i++) { 115 | colors.push(color[0], color[1], color[2], color[3]); 116 | } 117 | osg.log(vertexes); 118 | 119 | g.getAttributes().Vertex = osg.BufferArray.create(gl.ARRAY_BUFFER, vertexes, 3 ); 120 | g.getAttributes().Color = osg.BufferArray.create(gl.ARRAY_BUFFER, colors, 4 ); 121 | var primitive = new osg.DrawArray(gl.LINE_STRIP, 0, vertexes.length/3); 122 | g.getPrimitives().push(primitive); 123 | return g; 124 | }; -------------------------------------------------------------------------------- /js/camera.js: -------------------------------------------------------------------------------- 1 | /** -*- compile-command: "jslint-cli camera.js" -*- 2 | * 3 | * Copyright (C) 2011 Cedric Pinson 4 | * 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | * Authors: 21 | * Cedric Pinson 22 | * 23 | */ 24 | 25 | function initializeCameraPath(keys) { 26 | var createKeyframeVec3 = function(k) { 27 | var key = []; 28 | key[0] = k[1]; 29 | key[1] = k[2]; 30 | key[2] = k[3]; 31 | key.time = k[0]; 32 | return key; 33 | }; 34 | 35 | var ks = []; 36 | var l = keys.length; 37 | var i; 38 | ks.duration = keys[l-1][0]; 39 | 40 | for ( i = 0; i < l; ++i ) { 41 | ks.push(createKeyframeVec3(keys[i])); 42 | } 43 | 44 | ks.last_access = undefined; 45 | ks.getVec3 = function(t, startIndex) { 46 | var i; 47 | var localt; 48 | var d; 49 | var key0; 50 | var key1; 51 | var t0,t1; 52 | var l = this.length; 53 | if (t >= this[l-1].time) { 54 | return this[l-1]; 55 | } 56 | if (t < this[0].time) { 57 | return this[0]; 58 | } 59 | 60 | var start = 0; 61 | if (startIndex !== undefined) { 62 | start = startIndex; 63 | } 64 | if (start === 0 && this.last_access !== undefined && this[this.last_access].time < t) { 65 | start = this.last_access; 66 | } 67 | for (i = start; i < l; ++i) { 68 | key0 = this[i]; 69 | key1 = this[i+1]; 70 | t0 = key0.time; 71 | t1 = key1.time; 72 | if ( t >= t0 && t < t1) { 73 | this.last_access = i; 74 | d = t1 - t0; 75 | localt = t - t0; 76 | return osg.Vec3.lerp(localt/d, key0, key1, []); 77 | } 78 | } 79 | }; 80 | 81 | return ks; 82 | } 83 | -------------------------------------------------------------------------------- /js/defuscate.js: -------------------------------------------------------------------------------- 1 | email_format = /\s*\(.+\)\s*/ 2 | 3 | jQuery.fn.defuscate = function() { 4 | return this.each(function() { 5 | $(this).html(String($(this).html()).replace(email_format, "@")); 6 | }); 7 | }; 8 | 9 | jQuery.fn.defuscate_mailto = function() { 10 | return this.each(function() { 11 | $(this).attr('href', String($(this).attr('href')).replace(email_format, "@")); 12 | }); 13 | }; -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | /** -*- compile-command: "jslint-cli main.js" -*- 2 | * 3 | * Copyright (C) 2011 Cedric Pinson 4 | * 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | * Authors: 21 | * Cedric Pinson 22 | * 23 | */ 24 | 25 | window.addEventListener("load", function() { start2(); }, true ); 26 | var Viewer; 27 | var start2 = function() { 28 | var webglBrowser = '' + 29 | 'This page requires a browser that supports WebGL.
' + 30 | 'Click here to upgrade your browser'; 31 | 32 | var otherProblem = '' + 33 | "It doesn't appear your computer can support WebGL.
" + 34 | 'Click here for more information'; 35 | 36 | var w,h; 37 | if (window.top == window ) { 38 | h = document.documentElement.clientHeight; 39 | w = document.documentElement.clientWidth; 40 | } else { 41 | h = window.parent.document.body.clientHeight; 42 | w = window.parent.document.body.clientWidth; 43 | } 44 | 45 | var canvas = document.getElementById("3DView"); 46 | canvas.width = w; 47 | canvas.height = h; 48 | var youtubeurl = "http://www.youtube.com/watch?v=DHup1JfEsXo"; 49 | var webglerror = function (msg) { 50 | var str = window.WebGLRenderingContext ? 51 | webglBrowser : 52 | otherProblem; 53 | 54 | jQuery('#error').append(str + ' or you can still watch it on youtube'); 55 | removeLoading(); 56 | }; 57 | 58 | var viewer = new osgViewer.Viewer(canvas, { antialias: true, 59 | preserveDrawingBuffer: false, 60 | alpha: true }, webglerror ); 61 | 62 | var numTexturesAvailableInVertexShader = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); 63 | osg.log("Nb Texture Unit in vertex shader " + numTexturesAvailableInVertexShader); 64 | if (numTexturesAvailableInVertexShader < 9) { 65 | var msg = "Requires 9 texture unit on vertex shader (" + numTexturesAvailableInVertexShader+ ")"; 66 | osg.log(msg); 67 | //jQuery('#loading').append('
' +
'); 68 | 69 | removeLoading(); 70 | jQuery('#error2').append(msg + '
Angle or low gpu can produce it, fix it:

firefox: go to about:config and set webgl.prefer-native-gl to true.
chrome: run chrome with the --use-gl=desktop command-line argument.

You can watch it on youtube'); 71 | return; 72 | } 73 | 74 | var cred = window.location.href.indexOf('#credits'); 75 | if (cred >=0) { 76 | removeLoading(); 77 | showCredits(); 78 | return; 79 | } 80 | 81 | var audioSound=document.getElementById('zik'); 82 | //audioSound.play(); 83 | //audioSound.volume = 0; 84 | 85 | 86 | viewer.init(); 87 | Viewer = viewer; 88 | viewer.setupManipulator(); 89 | 90 | var keys = initializeCameraPath(cameraPath); 91 | var target = initializeCameraPath(targetPath); 92 | 93 | //var cameraTarget = [ 0.7 , 0.7, 0.5 ]; 94 | setEqualizerCameraPosition = function() { 95 | var t = this.timeStart; 96 | viewer.getManipulator().getInverseMatrix = function() { 97 | var position = keys.getVec3(audioSound.currentTime - t); 98 | var cameraTarget = target.getVec3(audioSound.currentTime - t); 99 | return osg.Matrix.makeLookAt(position, 100 | cameraTarget, 101 | [0,0,1], 102 | []); 103 | }; 104 | }; 105 | 106 | 107 | var grp = new osg.Node(); 108 | viewer.view.setClearColor([0.0, 0.0, 0.0, 0.0]); 109 | 110 | viewer.view.setComputeNearFar(false); 111 | var ratio = w / h; 112 | viewer.view.setProjectionMatrix(osg.Matrix.makePerspective(60.0, ratio, 0.1, 100.0)); 113 | 114 | grp.addChild(initParticles()); 115 | viewer.setScene(grp); 116 | 117 | //grp.addChild(createSceneText()); 118 | viewer.getManipulator().computeHomePosition(); 119 | 120 | 121 | var MainUpdate = function() { }; 122 | MainUpdate.prototype = { 123 | update: function(node, nv) { 124 | node.traverse(nv); 125 | } 126 | }; 127 | 128 | grp.setUpdateCallback(new MainUpdate()); 129 | 130 | 131 | 132 | viewer.run(); 133 | }; 134 | -------------------------------------------------------------------------------- /js/particles.js: -------------------------------------------------------------------------------- 1 | /** -*- compile-command: "jslint-cli particles.js" -*- 2 | * 3 | * Copyright (C) 2011 Cedric Pinson 4 | * 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | * Authors: 21 | * Cedric Pinson 22 | * 23 | */ 24 | 25 | 26 | var initParticles = function() { 27 | var optionsURL = function() { 28 | var vars = [], hash; 29 | var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); 30 | for(var i = 0; i < hashes.length; i++) 31 | { 32 | hash = hashes[i].split('='); 33 | vars.push(hash[0]); 34 | vars[hash[0]] = hash[1]; 35 | } 36 | return vars; 37 | }; 38 | 39 | var root = new osg.Node(); 40 | root.setNodeMask(0); 41 | var textureSize = [512, 512]; 42 | textureSize = [1024, 1024]; 43 | textureSize = [1024, 512]; 44 | textureSize = [512, 512]; 45 | 46 | var createParticlesShader = function() { 47 | var vertex = [ 48 | "", 49 | "#ifdef GL_ES", 50 | "precision highp float;", 51 | "#endif", 52 | "attribute vec3 Vertex;", 53 | "attribute vec2 TexCoord0;", 54 | "uniform mat4 ProjectionMatrix;", 55 | "varying vec2 FragTexCoord0;", 56 | "void main(void) {", 57 | " gl_Position = ProjectionMatrix * vec4(Vertex, 1.0);", 58 | " FragTexCoord0 = TexCoord0;", 59 | "}", 60 | "" 61 | ].join('\n'); 62 | 63 | var fragment = [ 64 | "#ifdef GL_ES", 65 | "precision highp float;", 66 | "#endif", 67 | "uniform float time;", 68 | "uniform float deltaTime;", 69 | "varying vec2 FragTexCoord0;", 70 | "uniform int bits;", 71 | "uniform int rtt;", 72 | "uniform sampler2D PreviousPosX;", 73 | "uniform sampler2D PreviousPosY;", 74 | "uniform sampler2D PreviousPosZ;", 75 | "uniform sampler2D PosX;", 76 | "uniform sampler2D PosY;", 77 | "uniform sampler2D PosZ;", 78 | "uniform sampler2D DistanceMap;", 79 | "uniform sampler2D model0;", 80 | "uniform sampler2D model1;", 81 | "uniform float scaleModel0;", 82 | "uniform float scaleModel1;", 83 | 84 | "uniform vec3 posModel0;", 85 | "uniform vec3 posModel1;", 86 | 87 | "uniform int freeze;", 88 | "uniform int forceNewLife;", 89 | "uniform float weightDistanceMap;", 90 | "uniform float weightVelocityField;", 91 | "uniform float solidModel;", 92 | "uniform float rotationZ;", 93 | "uniform float rotationX;", 94 | "uniform mat4 modelMatrix;", 95 | "uniform float modelRotationZ;", 96 | "uniform float modelRotationX;", 97 | "uniform float seed;", 98 | "uniform float windIntro;", 99 | 100 | "uniform float modelRatio;", 101 | "uniform float showModel;", 102 | 103 | "uniform float equalizer;", 104 | "uniform float equalizerLevel0;", 105 | "uniform float equalizerLevel1;", 106 | "uniform float equalizerLevel2;", 107 | "uniform float equalizerLevel3;", 108 | 109 | "uniform int introTextScene;", 110 | "uniform int equalizerScene;", 111 | 112 | "const vec3 worldCenter = vec3(0.5, 0.5, 0.5);", 113 | 114 | "float life;", 115 | "float distance;", 116 | "float material;", 117 | "const float PI = 3.1415926535;", 118 | "vec3 targetVec;", 119 | "const int equaNumberDisplay = 4;", 120 | "const int equaNumber = 4;", 121 | "const float equaRange = 0.5;", 122 | "vec3 equaBottom[equaNumber];", 123 | "vec3 equaSize[equaNumber];", 124 | "float equaLevel[equaNumber];", 125 | "const vec3 equaBottom0 = vec3(0.2, 0.1, 0.2);", 126 | "const vec3 equaSize0 = vec3(0.1, 0.5, 0.5);", 127 | 128 | "const vec3 equaBottom1 = vec3(0.4, 0.1, 0.2);", 129 | "const vec3 equaSize1 = vec3(0.1, 0.5, 0.5);", 130 | 131 | "const vec3 equaBottom2 = vec3(0.6, 0.1, 0.2);", 132 | "const vec3 equaSize2 = vec3(0.1, 0.5, 0.5);", 133 | 134 | "const vec3 equaBottom3 = vec3(0.8, 0.1, 0.2);", 135 | "const vec3 equaSize3 = vec3(0.1, 0.5, 0.5);", 136 | 137 | "float unpack(vec4 vec) {", 138 | " return vec[0] * 255.0 / 256.0 + vec[1] * 255.0 / (256.0 * 256.0) + vec[2] * 255.0 / (256.0 * 256.0 * 256.0);", 139 | "}", 140 | "vec4 pack(float value) {", 141 | " return vec4(floor(value * 256.0)/255.0, floor(fract(value * 256.0) * 256.0)/255.0 , floor(fract(value * 65536.0) * 256.0)/255.0, 0.0);", 142 | "}", 143 | 144 | "vec2 getModelBaseUV() {", 145 | " float v = (FragTexCoord0.y - 0.5)*2.0;", 146 | " float u = FragTexCoord0.x;", 147 | " u = (floor(u*512.0))/512.0;", 148 | " return vec2(u,v);", 149 | "}", 150 | 151 | "vec3 getModel0(vec2 uvx, vec2 uvy, vec2 uvz) {", 152 | " float x = unpack(texture2D( model0, uvx));", 153 | " float y = unpack(texture2D( model0, uvz));", 154 | " float z = unpack(texture2D( model0, uvy));", 155 | " return vec3(x,y,z);", 156 | "}", 157 | 158 | "vec3 getModel1(vec2 uvx, vec2 uvy, vec2 uvz) {", 159 | " float x = unpack(texture2D( model1, uvx));", 160 | " float y = unpack(texture2D( model1, uvz));", 161 | " float z = unpack(texture2D( model1, uvy));", 162 | " return vec3(x,y,z);", 163 | "}", 164 | "vec3 getModel(float ratio) {", 165 | " vec3 modelPosition = vec3(0.7,0.7,0.5);", 166 | " vec2 uvx = getModelBaseUV();", 167 | " vec2 uvy = uvx + vec2(1.0/2048.0, 0.0);", 168 | " vec2 uvz = uvx + vec2(2.0/2048.0, 0.0);", 169 | " vec3 centerPos = getModel0(uvx, uvy, uvz)-worldCenter;", 170 | " vec3 centerPos2 = getModel1(uvx, uvy, uvz)-worldCenter;", 171 | " vec3 finalPos = posModel0 + (modelMatrix * (vec4(centerPos* scaleModel0, 1.0))).xyz;", 172 | " vec3 finalPos2 = posModel1 + (modelMatrix * (vec4(centerPos2* scaleModel1, 1.0))).xyz;", 173 | " vec3 rrr = finalPos*(1.0-modelRatio) + modelRatio*finalPos2;", 174 | " return rrr;", 175 | "}", 176 | 177 | "void initEquaArrays() {", 178 | " equaBottom[0] = equaBottom0;", 179 | " equaBottom[1] = equaBottom1;", 180 | " equaBottom[2] = equaBottom2;", 181 | " equaBottom[3] = equaBottom3;", 182 | " equaSize[0] = equaSize0;", 183 | " equaSize[1] = equaSize1;", 184 | " equaSize[2] = equaSize2;", 185 | " equaSize[3] = equaSize3;", 186 | " equaLevel[0] = equalizerLevel0;", 187 | " equaLevel[1] = equalizerLevel1;", 188 | " equaLevel[2] = equalizerLevel2;", 189 | " equaLevel[3] = equalizerLevel3;", 190 | "}", 191 | "int pointInsideBoundingBox(vec3 center, vec3 size, vec3 pos) {", 192 | " vec3 diff = center - pos;", 193 | " if (diff[0] > size[0] || diff[0] < -size[0]) {", 194 | " return 0;", 195 | " }", 196 | " if (diff[1] > size[1] || diff[1] < -size[1]) {", 197 | " return 0;", 198 | " }", 199 | " if (diff[2] > size[2] || diff[2] < -size[2]) {", 200 | " return 0;", 201 | " }", 202 | " return 1;", 203 | "}", 204 | 205 | "vec3 getSpawnModel(float offset) {", 206 | " float size = 0.2;", 207 | " float a = 2.0 * 3.14159 * FragTexCoord0.x;", 208 | " float b = 2.0 * 3.14159 * FragTexCoord0.y;", 209 | " vec3 pos = worldCenter + vec3(cos(a), cos(a)+sin(b), cos(b)) * size;", 210 | " material = 0.0;", 211 | " return pos;", 212 | "}", 213 | "", 214 | "vec3 getSpawnPositionBoundingBox(vec3 center, vec3 size, float offset, float y) {", 215 | " vec3 corner = center - size*0.5;", 216 | " vec3 pos = vec3(size.x*y , 0.0*offset , size.z * FragTexCoord0.x)+corner;", 217 | " material = 0.0;", 218 | " distance = 0.0;", 219 | " return pos;", 220 | "}", 221 | "vec3 getSpawnPosition2(float offset) {", 222 | " vec3 size = vec3(0.9, 0.0, 0.5);", 223 | " vec3 corner = worldCenter - size*0.5;", 224 | " vec3 pos = vec3(size.x * FragTexCoord0.x*(1.0 + 5.0*offset), 0.0*(-offset + 0.1 + 0.1*cos(4.0*FragTexCoord0.x)), size.z*FragTexCoord0.y + 0.05*cos(4.0*FragTexCoord0.x))+corner;", 225 | " material = 0.0;", 226 | " return pos;", 227 | "}", 228 | 229 | "vec3 getSpawnPosition(float offset) {", 230 | " if (equalizerScene == 1) {", 231 | " if (FragTexCoord0.y < equaRange) {", 232 | " float step = equaRange/float(equaNumber);", 233 | " for (int i = 0; i < equaNumberDisplay; i++) {", 234 | " if (FragTexCoord0.y < float(i+1)*step) {", 235 | " vec3 bottom = equaBottom[i];", 236 | " vec3 size = equaSize[i];", 237 | " vec3 center = vec3(bottom.x, bottom.y, bottom.z+size.z/2.0);", 238 | " vec4 texel = texture2D( DistanceMap, FragTexCoord0);", 239 | 240 | " return getSpawnPositionBoundingBox(center, size, -offset*.03, (FragTexCoord0.y-(float(i)*step))/step + texel.g*texel[i]*step*float(i));", 241 | " }", 242 | " }} else {", 243 | " material = 0.0;", 244 | " return getModel(modelRatio);", 245 | " }", 246 | " }", 247 | " if (introTextScene == 1) {", 248 | " return getSpawnPosition2(0.0*offset);", 249 | " }", 250 | " material = 0.0;", 251 | " return vec3(0.0, -1000000.0, 0.0);", 252 | 253 | " //return getSpawnModel(offset);", 254 | " vec3 size = vec3(0.7, 0.0, 0.4);", 255 | " vec3 corner = worldCenter - size*0.5;", 256 | " vec3 pos = vec3(size.x* FragTexCoord0.x, -offset + 0.1 + 0.1*cos(4.0*FragTexCoord0.x), size.z*FragTexCoord0.y + 0.05*cos(4.0*FragTexCoord0.x))+corner;", 257 | " material = 0.0;", 258 | " return pos;", 259 | "}", 260 | "vec3 getRotationalVelocityField(vec3 pos, vec3 axis, float speed) {", 261 | " float rotationalSpeed = 1.0;", 262 | " vec3 fromCenter = pos-vec3(0.5,0.5,pos[2]);", 263 | " vec3 vec = cross(axis, pos-vec3(0.5,0.5,pos[2]) );", 264 | " float dist = length(fromCenter)*10.0 * speed;", 265 | " return vec*dist;", 266 | "}", 267 | "vec3 getVelocityField(vec3 pos) {", 268 | " float t = mod(time,15.0); //mod(time, 5.0);", 269 | " float vx = 0.0+cos(0.5+2.0*(pos.x*pos.x*t));", 270 | " float vy = cos(4.0*(pos.y*t+ seed*0.5)) + seed * sin(4.0*pos.x*t*t);", 271 | " float vz = cos(pos.z*2.0*t);", 272 | " vec3 vel = vec3( vx, vy, vz);", 273 | " return normalize(vel);", 274 | "}", 275 | "vec3 getPreviousPosition() {", 276 | " vec4 p0 = texture2D( PreviousPosX, vec2(FragTexCoord0.x, FragTexCoord0.y));", 277 | " vec4 p1 = texture2D( PreviousPosY, vec2(FragTexCoord0.x, FragTexCoord0.y));", 278 | " vec4 p2 = texture2D( PreviousPosZ, vec2(FragTexCoord0.x, FragTexCoord0.y));", 279 | " return vec3(unpack(p0), unpack(p1), unpack(p2));", 280 | "}", 281 | "vec3 getCurrentPosition() {", 282 | " vec4 p0 = texture2D( PosX, vec2(FragTexCoord0.x, FragTexCoord0.y));", 283 | " vec4 p1 = texture2D( PosY, vec2(FragTexCoord0.x, FragTexCoord0.y));", 284 | " vec4 p2 = texture2D( PosZ, vec2(FragTexCoord0.x, FragTexCoord0.y));", 285 | " life = p0[3];", 286 | " material = p2[3];", 287 | " distance = p1[3];", 288 | " return vec3(unpack(p0), unpack(p1), unpack(p2));", 289 | "}", 290 | "float getDistance(vec3 pos) {", 291 | " float d = texture2D( DistanceMap, vec2(pos.x, pos.z)).b;", 292 | " return d;", 293 | " float d2 = 2.0*abs(0.5-pos.y);", 294 | " return max(d2,d);", 295 | "}", 296 | "vec3 getDirection(vec3 pos) {", 297 | " vec4 d = texture2D( DistanceMap, vec2(pos.x, pos.z));", 298 | " vec2 grad = d.rg;", 299 | " vec3 dir = vec3(0.5-grad[0], 0.125*(0.5-pos.y), 0.5-grad[1]);", 300 | " //dir = normalize(dir) * (1.0 - d.b);", 301 | " dir = normalize(dir);", 302 | " return dir;", 303 | "}", 304 | "vec2 computeUV(vec3 center, vec3 size , vec3 pos) {", 305 | " vec3 pos2 = pos;", 306 | " pos2 = pos2 / vec3(size.x, 1.0, size.z);", 307 | " return vec2(pos2.x + 0.5, pos2.z + 0.5);", 308 | "}", 309 | "int computeEqualizer(vec3 currentPosition, vec3 bottom, vec3 size, float level) {", 310 | " size.z *= level;", 311 | " vec3 center = bottom + vec3(0.0, 0.0, size.z/2.0);", 312 | " if (pointInsideBoundingBox(center, size, currentPosition) == 0) {", 313 | " return 0;", 314 | " }", 315 | " vec3 diff = currentPosition - center;", 316 | " vec4 texel = texture2D( DistanceMap, computeUV(center, size, diff));", 317 | " vec2 grad = texel.rg;", 318 | " vec3 dir = vec3(0.5-grad[0], 0.125*(0.5-currentPosition.y), 0.5-grad[1]);", 319 | " dir = normalize(dir);", 320 | " targetVec += dir * weightDistanceMap*0.4;", 321 | " //distance = 1.0;", 322 | " if (weightDistanceMap > 0.001) {", 323 | " distance = texel.b * weightDistanceMap;", 324 | " }", 325 | " return 1;", 326 | "}", 327 | 328 | 329 | 330 | "vec3 verlet(vec3 prevPosition, vec3 currentPosition, float dt) {", 331 | " if (introTextScene == 1) { // need to have a flag for the text part", 332 | " currentPosition = worldCenter+(modelMatrix * vec4(currentPosition-worldCenter,1.0)).xyz;", 333 | " }", 334 | " float wind = 1.0;", 335 | " vec3 velocity = (currentPosition-prevPosition);", 336 | " vec3 acceleration = vec3(0.0, 0.0, 0.0*(-9.81 + 9.5));", 337 | " targetVec = vec3(0.0,0.0,0.0);", 338 | " //targetVec = getVelocityField(currentPosition)*weightVelocityField;", 339 | " if (rotationZ >= 0.01) {", 340 | " targetVec += getRotationalVelocityField(currentPosition, vec3(0.0, 0.0, 1.0), rotationZ);", 341 | " }", 342 | 343 | " if (introTextScene == 1) { // need to have a flag for the text part", 344 | " if (rotationX >= 0.01) {", 345 | " targetVec += getRotationalVelocityField(currentPosition, vec3(1.0, 0.0, 0.0), rotationX);", 346 | " }", 347 | " targetVec += getDirection(currentPosition)*weightDistanceMap*0.4;", 348 | " wind = windIntro;", 349 | " if (weightDistanceMap > 0.001) {", 350 | " distance = getDistance(currentPosition)*weightDistanceMap;", 351 | " }", 352 | " if (freeze == 1) {", 353 | " if ( distance > 0.3) {", 354 | " material = distance;", 355 | " }", 356 | " }", 357 | " } else if (equalizerScene == 1) {", 358 | " if (FragTexCoord0.y < equaRange) {", 359 | 360 | " if (computeEqualizer(currentPosition, equaBottom0, equaSize0, equalizerLevel0) == 0) { ", 361 | " if (computeEqualizer(currentPosition, equaBottom1, equaSize1, equalizerLevel1) == 0) {", 362 | " if (computeEqualizer(currentPosition, equaBottom2, equaSize2, equalizerLevel2) == 0) {", 363 | " computeEqualizer(currentPosition, equaBottom3, equaSize3, equalizerLevel3);", 364 | " } } } ", 365 | " if ( distance > 0.5) {", 366 | " material = distance;", 367 | " }", 368 | " } else {", 369 | " //life = 0.6;", 370 | " //life = 0.6;", 371 | " material = showModel;", 372 | " distance = 1.0;", 373 | " wind = 0.1;", 374 | " vec3 rrr = getModel(modelRatio);", 375 | " vec3 vec = rrr-currentPosition;", 376 | " distance = (0.5-length(vec))/0.5;", 377 | " distance = max(distance, 1.0);", 378 | " targetVec += vec*5.0;", 379 | " targetVec += 3.0*getVelocityField(currentPosition)*weightVelocityField;", 380 | " if (rotationX >= 0.01) {", 381 | " targetVec += getRotationalVelocityField(currentPosition, vec3(1.0, 0.0, 0.0), rotationX);", 382 | " }", 383 | " //targetVec *= 0.0;", 384 | " //velocity *= 0.0;", 385 | " //currentPosition = rrr;", 386 | " }", 387 | " }", 388 | "", 389 | " acceleration += targetVec ;", //* 0.5;", 390 | " ", 391 | " float l = length(velocity);", 392 | " vec3 dir = velocity;", 393 | " float maxSpeed = 0.005;", 394 | " if (l > 0.001) {", 395 | " dir = normalize(velocity);", 396 | " acceleration += -dir * 0.35 * wind;", 397 | " velocity = dir * min(maxSpeed, l); //cap velocity", 398 | " }", 399 | " vec3 next = (currentPosition + velocity + acceleration * (dt * dt));", 400 | " return next;", 401 | "}", 402 | "", 403 | "void main(void) {", 404 | " if (equalizerScene == 1) {", 405 | " initEquaArrays();", 406 | " }", 407 | 408 | " float dt = 1.0/60.0;", 409 | " vec3 previousPos = getPreviousPosition();", 410 | " vec3 currentPos = getCurrentPosition();", 411 | " if (equalizerScene == 1) {", 412 | " if (FragTexCoord0.y < equaRange) {", 413 | " life = max(life-dt, 0.0);", 414 | " } else {", 415 | " life = max(life-dt/8.0, 0.0);", 416 | " }", 417 | " }", 418 | " if (material > 0.3 && equalizerScene == 0) {", 419 | " life = max(life-dt/3.0, 0.0);", 420 | " } else {", 421 | " life = max(life-dt/1.5, 0.0);", 422 | " }", 423 | " vec3 next;", 424 | " if (forceNewLife == 1) {", 425 | " life = 3.0/255.0;", 426 | " next = currentPos;", 427 | " } else {", 428 | " if (life <= 3.0/255.0 && life >= 1.0/255.0) {", 429 | " next = getSpawnPosition(0.0);", 430 | " } else if (life < 1.0/255.0) {", 431 | " life = sin((FragTexCoord0.y + FragTexCoord0.x*1.3333)*(time * seed + 3.333333)*0.2) * 0.4 + 0.5;", 432 | " next = getSpawnPosition(0.005);", 433 | " } else {", 434 | " next = currentPos*solidModel + (1.0 - solidModel) * verlet(previousPos, currentPos, dt);", 435 | " }", 436 | " }", 437 | " vec4 x = pack(next.x);", 438 | " vec4 y = pack(next.y);", 439 | " vec4 z = pack(next.z);", 440 | " vec4 value;", 441 | " if (bits == 0) {", 442 | " value = x;", 443 | " value[3] = life;", 444 | " } else if (bits == 1) {", 445 | " value = y;", 446 | " value[3] = distance;", 447 | " } else if (bits == 2){", 448 | " value = z;", 449 | " value[3] = material;", 450 | " }", 451 | " gl_FragColor = value;", 452 | "}", 453 | "" 454 | ].join('\n'); 455 | 456 | var program = new osg.Program( 457 | osg.Shader.create(gl.VERTEX_SHADER, vertex), 458 | osg.Shader.create(gl.FRAGMENT_SHADER, fragment)); 459 | return program; 460 | }; 461 | 462 | var ready = function() { 463 | osg.log("ready"); 464 | root.setNodeMask(~0x0); 465 | }; 466 | 467 | var setNeareastFilter = function(texture) { 468 | texture.setMinFilter('NEAREST'); 469 | texture.setMagFilter('NEAREST'); 470 | }; 471 | 472 | // wait at list one second 473 | var loadingStart = new Date().getTime(); 474 | var durationLoading = 1.0; 475 | var loadingComplete = function() { 476 | var funcToComplete = function() { 477 | removeLoading(); 478 | setTimeout(function() {ready(); }, 500); 479 | }; 480 | 481 | loadingComplete.nbLoad--; 482 | if (loadingComplete.nbLoad < 0) { 483 | osg.log("loadingComplete called more than needed"); 484 | } 485 | if (loadingComplete.nbLoad === 0) { 486 | var finished = new Date().getTime(); 487 | var diff = (finished-loadingStart)/1000.0; 488 | if ((diff-0.5) < durationLoading) { 489 | setTimeout(funcToComplete, (durationLoading-diff)*1000.0); 490 | } else { 491 | funcToComplete(); 492 | } 493 | } 494 | }; 495 | loadingComplete.nbLoad = 0; 496 | loadingComplete.addRessource = function() { 497 | loadingComplete.nbLoad++; 498 | }; 499 | 500 | var texturePoint = new osg.Texture(); 501 | var loadPoint = function() { 502 | var img = new Image; 503 | loadingComplete.addRessource(); 504 | img.onload = function() { loadingComplete() }; 505 | img.src = 'point.png'; 506 | texturePoint.setImage(img); 507 | //setNeareastFilter(textureEqua); 508 | }; 509 | 510 | var textureEqua = new osg.Texture(); 511 | var loadEqua = function() { 512 | var img = new Image; 513 | loadingComplete.addRessource(); 514 | img.onload = function() { loadingComplete() }; 515 | img.src = 'equa2_grad.png'; 516 | textureEqua.setImage(img); 517 | setNeareastFilter(textureEqua); 518 | }; 519 | 520 | var textureFR = new osg.Texture(); 521 | var loadFR = function() { 522 | var img = new Image; 523 | loadingComplete.addRessource(); 524 | img.onload = function() { loadingComplete() }; 525 | img.src = 'FRequency_grad.png'; 526 | textureFR.setImage(img); 527 | setNeareastFilter(textureFR); 528 | }; 529 | 530 | var textureSY = new osg.Texture(); 531 | var loadSY = function() { 532 | var img = new Image; 533 | loadingComplete.addRessource(); 534 | img.onload = function() { loadingComplete() }; 535 | img.src = 'SynRJ_grad.png'; 536 | textureSY.setImage(img); 537 | setNeareastFilter(textureSY); 538 | }; 539 | 540 | var textureBy = new osg.Texture(); 541 | var loadBy = function() { 542 | var img = new Image; 543 | loadingComplete.addRessource(); 544 | img.onload = function() { loadingComplete() }; 545 | img.src = 'By_grad.png'; 546 | textureBy.setImage(img); 547 | setNeareastFilter(textureBy); 548 | }; 549 | 550 | var textureTitle = new osg.Texture(); 551 | var loadTitle = function() { 552 | var img = new Image; 553 | loadingComplete.addRessource(); 554 | img.onload = function() { loadingComplete() }; 555 | img.src = 'Title_grad.png'; 556 | textureTitle.setImage(img); 557 | setNeareastFilter(textureTitle); 558 | }; 559 | 560 | var textureModel0 = new osg.Texture(); 561 | var loadModel0 = function() { 562 | var img = new Image; 563 | loadingComplete.addRessource(); 564 | img.onload = function() { loadingComplete() }; 565 | img.src = 'model0.png'; 566 | textureModel0.setImage(img); 567 | setNeareastFilter(textureModel0); 568 | }; 569 | 570 | var textureModel1 = new osg.Texture(); 571 | var loadModel1 = function() { 572 | var img = new Image; 573 | loadingComplete.addRessource(); 574 | img.onload = function() { loadingComplete() }; 575 | img.src = 'model1.png'; 576 | textureModel1.setImage(img); 577 | setNeareastFilter(textureModel1); 578 | }; 579 | 580 | var textureModel2 = new osg.Texture(); 581 | var loadModel2 = function() { 582 | var img = new Image; 583 | loadingComplete.addRessource(); 584 | img.onload = function() { loadingComplete() }; 585 | img.src = 'model2.png'; 586 | textureModel2.setImage(img); 587 | setNeareastFilter(textureModel2); 588 | }; 589 | 590 | var textureModel3 = new osg.Texture(); 591 | var loadModel3 = function() { 592 | var img = new Image; 593 | loadingComplete.addRessource(); 594 | img.onload = function() { loadingComplete() }; 595 | img.src = 'model3.png'; 596 | textureModel3.setImage(img); 597 | setNeareastFilter(textureModel3); 598 | }; 599 | 600 | var textureModel4 = new osg.Texture(); 601 | var loadModel4 = function() { 602 | var img = new Image; 603 | loadingComplete.addRessource(); 604 | img.onload = function() { loadingComplete() }; 605 | img.src = 'model4.png'; 606 | textureModel4.setImage(img); 607 | setNeareastFilter(textureModel4); 608 | }; 609 | 610 | var textureModel5 = new osg.Texture(); 611 | var loadModel5 = function() { 612 | var img = new Image; 613 | loadingComplete.addRessource(); 614 | img.onload = function() { loadingComplete() }; 615 | img.src = 'model5.png'; 616 | textureModel5.setImage(img); 617 | setNeareastFilter(textureModel5); 618 | }; 619 | 620 | var textureModel6 = new osg.Texture(); 621 | var loadModel6 = function() { 622 | var img = new Image; 623 | loadingComplete.addRessource(); 624 | img.onload = function() { loadingComplete() }; 625 | img.src = 'model6.png'; 626 | textureModel6.setImage(img); 627 | setNeareastFilter(textureModel6); 628 | }; 629 | 630 | 631 | var defaultImage; 632 | var loadDefaultImage = function() { 633 | defaultImage = new Image(); 634 | loadingComplete.addRessource(); 635 | defaultImage.onload = function() { loadingComplete() }; 636 | defaultImage.src = "texture_" + textureSize[0] + "_" + textureSize[1] + ".png"; 637 | }; 638 | 639 | // loading 640 | loadDefaultImage(); 641 | loadPoint(); 642 | loadEqua(); 643 | loadFR(); 644 | loadSY(); 645 | loadBy(); 646 | loadTitle(); 647 | loadModel0(); 648 | loadModel1(); 649 | loadModel2(); 650 | loadModel3(); 651 | loadModel4(); 652 | loadModel5(); 653 | loadModel6(); 654 | 655 | 656 | var textureIndex = 0; 657 | var createTexture = function() { 658 | var texture = new osg.Texture(); 659 | texture.setImage(defaultImage); 660 | texture.setTextureSize(textureSize[0], textureSize[1]); 661 | texture.setMinFilter('NEAREST'); 662 | texture.setMagFilter('NEAREST'); 663 | texture.indexID = textureIndex; 664 | textureIndex++; 665 | return texture; 666 | }; 667 | 668 | var physicsTextures = [ 669 | [ createTexture(), createTexture(), createTexture()], 670 | [ createTexture(), createTexture(), createTexture()], 671 | [ createTexture(), createTexture(), createTexture()] 672 | ]; 673 | 674 | 675 | var uniformTime = osg.Uniform.createFloat1(0.0,'time'); 676 | var freeze = osg.Uniform.createInt1(0,'freeze'); 677 | var weightVelocityField = osg.Uniform.createFloat1(1,'weightVelocityField'); 678 | var weightDistanceMap = osg.Uniform.createFloat1(1,'weightDistanceMap'); 679 | var forceNewLife = osg.Uniform.createInt1(0,'forceNewLife'); 680 | var solidModel = osg.Uniform.createFloat1(1.0,'solidModel'); 681 | var rotationZ = osg.Uniform.createFloat1(0.0,'rotationZ'); 682 | var rotationX = osg.Uniform.createFloat1(0.0,'rotationX'); 683 | var modelMatrix = osg.Uniform.createMatrix4(osg.Matrix.makeIdentity([]),'modelMatrix'); 684 | var uniformSeed = osg.Uniform.createFloat1(Math.random(),'seed'); 685 | var uniformEqualizer = osg.Uniform.createFloat1(0.0,'equalizer'); 686 | var uniformEqualizerLevel0 = osg.Uniform.createFloat1(0.0,'equalizerLevel0'); 687 | var uniformEqualizerLevel1 = osg.Uniform.createFloat1(0.0,'equalizerLevel1'); 688 | var uniformEqualizerLevel2 = osg.Uniform.createFloat1(0.0,'equalizerLevel2'); 689 | var uniformEqualizerLevel3 = osg.Uniform.createFloat1(0.0,'equalizerLevel3'); 690 | 691 | var uniformEqualizerScene = osg.Uniform.createInt1(0,'equalizerScene'); 692 | var uniformIntroTextScene = osg.Uniform.createInt1(0,'introTextScene'); 693 | var uniformWindIntro = osg.Uniform.createFloat1(1.0, 'windIntro'); 694 | 695 | var uniformModelRatio = osg.Uniform.createFloat1(0.0, 'modelRatio'); 696 | var uniformShowModel = osg.Uniform.createFloat1(0.0, 'showModel'); 697 | 698 | var uniformScaleModel1 = osg.Uniform.createFloat1(1.0, 'scaleModel1'); 699 | var uniformScaleModel0 = osg.Uniform.createFloat1(1.0, 'scaleModel0'); 700 | 701 | var uniformPositionModel1 = osg.Uniform.createFloat3([ 0.0, 0.0, 0.0], 'posModel1'); 702 | var uniformPositionModel0 = osg.Uniform.createFloat3([ 0.0, 0.0, 0.0], 'posModel0'); 703 | 704 | var Physics = function(cameras, textures) { 705 | this.cameras = cameras; 706 | 707 | var node = new osg.Node(); 708 | node.addChild(cameras[0]); 709 | node.addChild(cameras[1]); 710 | node.addChild(cameras[2]); 711 | this.root = node; 712 | this.index = 0; 713 | 714 | this.buffers = textures; 715 | this.time = uniformTime; 716 | 717 | this.setNodeMask(); 718 | }; 719 | 720 | Physics.prototype = { 721 | setNodeMask: function() { 722 | this.cameras[0].setNodeMask(0); 723 | this.cameras[1].setNodeMask(0); 724 | this.cameras[2].setNodeMask(0); 725 | this.cameras[this.index].setNodeMask(~0x0); 726 | }, 727 | switchBuffer: function() { 728 | this.index = (this.index + 1) %3; 729 | this.setNodeMask(); 730 | }, 731 | getDisplayTexture: function() { 732 | return this.buffers[this.index]; 733 | } 734 | }; 735 | 736 | var createPhysics = function() { 737 | 738 | var previousPosX = osg.Uniform.createInt1(0,'PreviousPosX'); 739 | var previousPosY = osg.Uniform.createInt1(1,'PreviousPosY'); 740 | var previousPosZ = osg.Uniform.createInt1(2,'PreviousPosZ'); 741 | 742 | var currentPosX = osg.Uniform.createInt1(3,'PosX'); 743 | var currentPosY = osg.Uniform.createInt1(4,'PosY'); 744 | var currentPosZ = osg.Uniform.createInt1(5,'PosZ'); 745 | 746 | var distanceMap = osg.Uniform.createInt1(6,'DistanceMap'); 747 | var model0 = osg.Uniform.createInt1(7,'model0'); 748 | var model1 = osg.Uniform.createInt1(8,'model1'); 749 | 750 | var viewport = new osg.Viewport(0,0,textureSize[0],textureSize[1]); 751 | 752 | var createCamera = function(bits, index) { 753 | 754 | var camera = new osg.Camera(); 755 | camera.setRenderOrder(osg.Camera.PRE_RENDER, 0); 756 | camera.setReferenceFrame(osg.Transform.ABSOLUTE_RF); 757 | camera.setClearMask(0); 758 | camera.useBits = "useBits " + bits; 759 | camera.setProjectionMatrixAsOrtho(0, 1, 0, 1, -1, 1); 760 | camera.setViewport(viewport); 761 | 762 | var quad = osg.createTexturedQuad(0, 0, 0, 763 | 1, 0, 0, 764 | 0, 1, 0); 765 | quad.useBits = camera.useBits; 766 | camera.addChild(quad); 767 | 768 | var prg = createParticlesShader(); 769 | var stateset = quad.getOrCreateStateSet(); 770 | 771 | stateset.setAttributeAndMode(prg); 772 | stateset.setAttributeAndMode(new osg.Depth('DISABLE')); 773 | stateset.addUniform(osg.Uniform.createInt1(bits,'bits')); 774 | 775 | stateset.addUniform(osg.Uniform.createInt1(index,'rtt')); 776 | 777 | stateset.addUniform(previousPosX); 778 | stateset.addUniform(previousPosY); 779 | stateset.addUniform(previousPosZ); 780 | stateset.addUniform(currentPosX); 781 | stateset.addUniform(currentPosY); 782 | stateset.addUniform(currentPosZ); 783 | stateset.addUniform(distanceMap); 784 | 785 | stateset.addUniform(uniformTime); 786 | stateset.addUniform(freeze); 787 | stateset.addUniform(forceNewLife); 788 | stateset.addUniform(weightVelocityField); 789 | stateset.addUniform(weightDistanceMap); 790 | stateset.addUniform(solidModel); 791 | stateset.addUniform(rotationZ); 792 | stateset.addUniform(rotationX); 793 | stateset.addUniform(modelMatrix); 794 | stateset.addUniform(uniformSeed); 795 | stateset.addUniform(uniformEqualizer); 796 | stateset.addUniform(uniformEqualizerScene); 797 | stateset.addUniform(uniformIntroTextScene); 798 | stateset.addUniform(uniformEqualizerLevel0); 799 | stateset.addUniform(uniformEqualizerLevel1); 800 | stateset.addUniform(uniformEqualizerLevel2); 801 | stateset.addUniform(uniformEqualizerLevel3); 802 | stateset.addUniform(uniformWindIntro); 803 | stateset.addUniform(uniformModelRatio); 804 | stateset.addUniform(uniformShowModel); 805 | 806 | stateset.addUniform(model0); 807 | stateset.addUniform(model1); 808 | stateset.addUniform(uniformScaleModel0); 809 | stateset.addUniform(uniformScaleModel1); 810 | 811 | stateset.addUniform(uniformPositionModel0); 812 | stateset.addUniform(uniformPositionModel1); 813 | 814 | var idx; 815 | idx = (index + 1)%3; 816 | stateset.setTextureAttributeAndMode(0, physicsTextures[idx][0]); 817 | stateset.setTextureAttributeAndMode(1, physicsTextures[idx][1]); 818 | stateset.setTextureAttributeAndMode(2, physicsTextures[idx][2]); 819 | 820 | idx = (index + 2)%3; 821 | stateset.setTextureAttributeAndMode(3, physicsTextures[idx][0]); 822 | stateset.setTextureAttributeAndMode(4, physicsTextures[idx][1]); 823 | stateset.setTextureAttributeAndMode(5, physicsTextures[idx][2]); 824 | 825 | //stateset.setTextureAttributeAndMode(6, textureDistance); 826 | 827 | camera.statesetGeometry = stateset; 828 | 829 | camera.attachTexture(gl.COLOR_ATTACHMENT0, physicsTextures[index][bits]); 830 | return camera; 831 | }; 832 | 833 | var cameras = []; 834 | for (var c = 0, l = 3; c < l; c++) { 835 | var grp = new osg.Node(); 836 | var x = createCamera(0, c); 837 | var y = createCamera(1, c); 838 | var z = createCamera(2, c); 839 | grp.addChild(x); 840 | grp.addChild(y); 841 | grp.addChild(z); 842 | cameras.push(grp); 843 | } 844 | var ph = new Physics(cameras,physicsTextures); 845 | return ph; 846 | }; 847 | 848 | 849 | var Render = function(node, stateset) { 850 | this.stateSet = stateset; 851 | this.root = node; 852 | }; 853 | Render.prototype = { 854 | setDisplayTexture: function(textureArray) { 855 | this.stateSet.setTextureAttributeAndMode(0, textureArray[0]); 856 | this.stateSet.setTextureAttributeAndMode(1, textureArray[1]); 857 | this.stateSet.setTextureAttributeAndMode(2, textureArray[2]); 858 | this.stateSet.setTextureAttributeAndMode(3, texturePoint); 859 | } 860 | }; 861 | 862 | var createRender = function() { 863 | var node = new osg.Node(); 864 | var geom = new osg.Geometry(); 865 | var elements = []; 866 | var sizex = textureSize[0]; 867 | var sizey = textureSize[1]; 868 | var i; 869 | for (i = 0; i < sizex; i++) { 870 | for (var j = 0; j < sizey; j++) { 871 | elements.push(i/sizex, j/sizey, 0); 872 | } 873 | } 874 | 875 | geom.getAttributes().Vertex = new osg.BufferArray(gl.ARRAY_BUFFER, elements, 3 ); 876 | geom.getPrimitives().push(new osg.DrawArrays(gl.POINTS,0,elements.length/3)); 877 | node.addChild(geom); 878 | var b = node.getBound(); 879 | b.set([0.5, 0.5, 0.5], 0.5); 880 | 881 | var vertex = [ 882 | "", 883 | "#ifdef GL_ES", 884 | "precision highp float;", 885 | "#endif", 886 | "attribute vec3 Vertex;", 887 | "uniform mat4 ModelViewMatrix;", 888 | "uniform mat4 ProjectionMatrix;", 889 | "uniform sampler2D X;", 890 | "uniform sampler2D Y;", 891 | "uniform sampler2D Z;", 892 | "uniform float equalizer;", 893 | "varying vec4 color;", 894 | "float life;", 895 | "float distance;", 896 | "float material;", 897 | "float unpack(vec4 vec) {", 898 | " return vec[0] * 255.0 / 256.0 + vec[1] * 255.0 / (256.0 * 256.0) + vec[2] * 255.0 / (256.0 * 256.0 * 256.0);", 899 | "}", 900 | "float getSmoothDead(float value) {", 901 | " return 1.0-pow(1.0-value,6.0);", 902 | "}", 903 | " // (2 + -((x-0.5)*(x-0.5) * 8))*0.5", 904 | "float getSmoothDead2(float x) {", 905 | " //return getSmoothDead(x);", 906 | " return (2.0 + -(pow(x-0.5,2.0) * 8.0))*0.5;", 907 | "}", 908 | "void main(void) {", 909 | " vec2 uv = vec2(Vertex.x, Vertex.y);", 910 | " vec4 xvec = texture2D( X, uv);", 911 | " vec4 yvec = texture2D( Y, uv);", 912 | " vec4 zvec = texture2D( Z, uv);", 913 | " life = xvec[3];", 914 | " distance = yvec[3];", 915 | " material = zvec[3];", 916 | " float x = unpack(xvec);", 917 | " float y = unpack(yvec);", 918 | " float z = unpack(zvec);", 919 | " vec4 p = vec4(x,y,z,0);", 920 | " vec4 v;", 921 | " v[3] = 1.0;", 922 | " v[0] = x;", 923 | " v[1] = y;", 924 | " v[2] = z;", 925 | " color = vec4(uv.x, uv.y, 0.0, 1.0);", 926 | " float alpha = getSmoothDead2(life);", 927 | " float distFromEdge = 1.0;", 928 | " color = vec4(x * alpha , y * alpha, z * alpha, alpha * distFromEdge);", 929 | " if (equalizer >0.0 && distance > 0.5) {", 930 | " float b = (1.0-distance);", 931 | " color = vec4(0.0, 0.0, 0.0, 1.0 * alpha * material);", 932 | " gl_Position = ProjectionMatrix * ModelViewMatrix * v;", 933 | " gl_PointSize = 2.0;", 934 | " return ;", 935 | " } else if (material > 0.3 && material < 0.9) {", 936 | " float b = (1.0-distance);", 937 | " color = vec4(0.0, 0.0, 0.0, 1.0 * alpha);", 938 | " gl_Position = ProjectionMatrix * ModelViewMatrix * v;", 939 | " gl_PointSize = 2.0;", 940 | " return;", 941 | " }", 942 | " //gl_Position = ProjectionMatrix * ModelViewMatrix * v;", 943 | " gl_Position = vec4(0.0,0.0,-10000.0,1.0); // clip it", 944 | " gl_PointSize = 2.0;", 945 | "}", 946 | "" 947 | ].join('\n'); 948 | 949 | var fragment = [ 950 | "", 951 | "#ifdef GL_ES", 952 | "precision highp float;", 953 | "#endif", 954 | "varying vec4 color;", 955 | "uniform sampler2D Point;", 956 | "void main(void) {", 957 | "if (color[3] < 0.01) {", 958 | " discard;", 959 | "}", 960 | "vec4 col = texture2D(Point, gl_PointCoord);", 961 | "col *= vec4(col.a, col.a, col.a ,1.0);", 962 | "gl_FragColor = col*color;", 963 | "}", 964 | "" 965 | ].join('\n'); 966 | 967 | var program = new osg.Program( 968 | new osg.Shader(gl.VERTEX_SHADER, vertex), 969 | new osg.Shader(gl.FRAGMENT_SHADER, fragment)); 970 | 971 | var stateset = geom.getOrCreateStateSet(); 972 | stateset.setAttributeAndMode(program); 973 | stateset.setAttributeAndMode(new osg.BlendFunc('ONE', 'ONE_MINUS_SRC_ALPHA')); 974 | 975 | stateset.addUniform(osg.Uniform.createInt1(0,"X")); 976 | stateset.addUniform(osg.Uniform.createInt1(1,"Y")); 977 | stateset.addUniform(osg.Uniform.createInt1(2,"Z")); 978 | stateset.addUniform(osg.Uniform.createInt1(3,"Point")); 979 | stateset.addUniform(uniformEqualizer); 980 | 981 | return new Render(node, stateset); 982 | }; 983 | 984 | var physics = createPhysics(); 985 | var render = createRender(); 986 | render.setDisplayTexture(physics.getDisplayTexture()); 987 | 988 | var models = [ textureModel0, textureModel1, textureModel2, textureModel3, textureModel4, textureModel5, textureModel6 ]; 989 | var modelsScale = [ 0.4, 990 | 0.2, 991 | 0.2, 992 | 0.2, 993 | 0.2, 994 | 0.5, 995 | 0.2 996 | ]; 997 | var modelsPos = [ [0.55,0.55,0.5], 998 | [0.7,0.7,0.5], 999 | [0.7,0.7,0.5], 1000 | [0.7,0.7,0.5], 1001 | [0.7,0.7,0.5], 1002 | [0.6,0.6,0.5], 1003 | [0.7,0.7,0.4] 1004 | ]; 1005 | var uniformsModelScale = [uniformScaleModel0, uniformScaleModel1 ]; 1006 | var uniformsModelPosition = [uniformPositionModel0, uniformPositionModel1 ]; 1007 | 1008 | var modelIndex = -1; 1009 | 1010 | changeModel = function() { 1011 | var st = physics.root.getOrCreateStateSet(); 1012 | if (modelIndex === -1) { 1013 | st.setTextureAttributeAndMode(7, models[0], osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1014 | uniformScaleModel0.get()[0] = modelsScale[0]; uniformScaleModel0.dirty(); 1015 | uniformPositionModel0.set(modelsPos[0]); 1016 | 1017 | modelIndex++; 1018 | } else { 1019 | var previousIndex = (modelIndex)%2; 1020 | var previousModel = modelIndex; 1021 | modelIndex++; 1022 | var nextIndex = (modelIndex)%2; 1023 | var nextModel = modelIndex; 1024 | 1025 | uniformsModelScale[previousIndex].get()[0] = modelsScale[previousModel]; uniformsModelScale[previousIndex].dirty(); 1026 | uniformsModelScale[nextIndex].get()[0] = modelsScale[nextModel]; uniformsModelScale[nextIndex].dirty(); 1027 | 1028 | uniformsModelPosition[previousIndex].set(modelsPos[previousModel]); 1029 | uniformsModelPosition[nextIndex].set(modelsPos[nextModel]); 1030 | 1031 | 1032 | uniformModelRatio.get()[0] = nextIndex; uniformModelRatio.dirty(); 1033 | 1034 | st.setTextureAttributeAndMode(7+previousIndex, models[previousModel], osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1035 | st.setTextureAttributeAndMode(7+nextIndex, models[nextModel], osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1036 | //osg.log("change model from " + previousIndex + "(" + previousModel + ") to " + nextIndex + "("+nextModel+")"); 1037 | } 1038 | }; 1039 | 1040 | 1041 | 1042 | var audioSound = document.getElementById('zik'); 1043 | var timeObjects = timeSetup(timeEvents); 1044 | var firstTime = true; 1045 | var FirstFrameCheckSoundBugHack = 0; 1046 | 1047 | var options = optionsURL(); 1048 | var UpdateCallback = function (physics, render) { 1049 | this.physics = physics; 1050 | this.render = render; 1051 | this.nbUpdate = 0; 1052 | this.previousAudioTime = 0.0; 1053 | }; 1054 | UpdateCallback.prototype = { 1055 | update: function(node, nv) { 1056 | 1057 | var t = audioSound.currentTime; //nv.getFrameStamp().getSimulationTime(); 1058 | t = 10.0 + 5.0*Math.cos(t); 1059 | uniformSeed.get()[0] = Math.random(); 1060 | uniformSeed.dirty(); 1061 | uniformTime.set([t]); 1062 | 1063 | // initialize spawn buffer at the beginning 1064 | if (this.nbUpdate === 0) { 1065 | //forceNewLife.set([1]); 1066 | solidModel.set([1.0]); 1067 | weightDistanceMap.set([10.0]); 1068 | } else if (this.nbUpdate === 1) { 1069 | solidModel.set([0.0]); 1070 | } else { 1071 | if (this.nbUpdate === 3) { 1072 | 1073 | osg.log("current audio was " + audioSound.currentTime); 1074 | audioSound.play(); 1075 | 1076 | this.fakeTimerStart = nv.getFrameStamp().getSimulationTime(); 1077 | this.fakeTimer = 0.0; 1078 | 1079 | if (options['time'] !== undefined) { 1080 | audioSound.currentTime = options['time']; 1081 | this.previousAudioTime = options['time']; 1082 | this.fakeTimer += options['time']; 1083 | } else { 1084 | audioSound.currentTime = 0; 1085 | this.previousAudioTime = 0; 1086 | } 1087 | 1088 | //this.previousAudioTime = 0; 1089 | 1090 | audioSound.volume = 1.0; 1091 | osg.log("start now at " + audioSound.currentTime); 1092 | } 1093 | 1094 | var at = 0.0; 1095 | var t = 0.0; 1096 | if (this.nbUpdate > 2) { 1097 | at = nv.getFrameStamp().getSimulationTime()-this.fakeTimerStart; 1098 | t = at; 1099 | 1100 | var dtAudio = at - this.previousAudioTime; 1101 | if (options['logtime'] !== undefined) { 1102 | osg.log("at " + at + " " + dtAudio); 1103 | } 1104 | 1105 | this.previousAudioTime = at; 1106 | Timeline.getGlobalInstance().update(dtAudio); 1107 | } 1108 | t = 10.0 + 5.0*Math.cos(t); 1109 | 1110 | weightVelocityField.set([0.0* (0.5 + 0.5*Math.cos(t*0.2))]); 1111 | weightDistanceMap.set([0.0 * (0.5 + 0.5*Math.cos(t*0.666666))]); 1112 | rotationZ.set([0 * timeObjects.FRQMusicRiff.value]); 1113 | rotationX.set([0 * timeObjects.FRQMusicRiff.value]); 1114 | 1115 | osg.Matrix.makeIdentity(modelMatrix.get()); 1116 | freeze.get()[0] = 0.0; freeze.dirty(); 1117 | 1118 | uniformEqualizerScene.get()[0] = 0; uniformEqualizerScene.dirty(); 1119 | uniformIntroTextScene.get()[0] = 0; uniformIntroTextScene.dirty(); 1120 | 1121 | if (timeObjects.EqualizerScene.value > 0.5) { 1122 | if (firstTime) { 1123 | forceNewLife.set([1]); 1124 | } else { 1125 | forceNewLife.set([0]); 1126 | } 1127 | firstTime = false; 1128 | 1129 | uniformEqualizerScene.get()[0] = 1; uniformEqualizerScene.dirty(); 1130 | uniformIntroTextScene.get()[0] = 0.0; uniformIntroTextScene.dirty(); 1131 | 1132 | this.physics.root.getOrCreateStateSet().setTextureAttributeAndMode(6, textureEqua, osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1133 | 1134 | 1135 | uniformEqualizer.get()[0] = 1.0; uniformEqualizer.dirty(); 1136 | 1137 | uniformEqualizerLevel0.get()[0] = timeObjects.FRQMusicSnare.value; uniformEqualizerLevel0.dirty(); 1138 | 1139 | uniformEqualizerLevel1.get()[0] = timeObjects.FRQMusicKick.value; uniformEqualizerLevel1.dirty(); 1140 | uniformEqualizerLevel2.get()[0] = (timeObjects.FRQMusicRiff.value + timeObjects.FRQMusicSound1.value + timeObjects.FRQMusicSound2.value + timeObjects.FRQMusicSound3.value); uniformEqualizerLevel2.dirty(); 1141 | uniformEqualizerLevel3.get()[0] = (timeObjects.FRQMusicSynth.value + timeObjects.FRQMusicVocal.value); uniformEqualizerLevel3.dirty(); 1142 | 1143 | uniformShowModel.get()[0] = timeObjects.EqualizerSceneShowModel.value; uniformShowModel.dirty(); 1144 | 1145 | rotationX.set([1.0]); 1146 | rotationZ.set([0.0]); 1147 | weightDistanceMap.set([1.0]); 1148 | freeze.set([1.0]); 1149 | 1150 | var vec = [0,0,0]; 1151 | rotationX.set([0.0]); 1152 | 1153 | var changeAtFirefoxLogo = 1.0-timeObjects.EqualizerSceneDisplayFirefox.value; 1154 | weightVelocityField.set([changeAtFirefoxLogo * 0.3* (0.5 + 0.5*Math.cos(t*0.2))]); 1155 | 1156 | osg.Matrix.makeRotate(Math.PI, 0,0,1, modelMatrix.get()); 1157 | osg.Matrix.preMult(modelMatrix.get(), osg.Matrix.makeRotate(Math.PI/3.0, 1,0,0, [])); 1158 | 1159 | var ffModelMatrixRotate = osg.Matrix.makeRotate(timeObjects.EqualizerSceneDisplayFirefox.value * (-((6.0+audioSound.currentTime)*0.5)), 0, 0, 1, []); 1160 | osg.Matrix.postMult(ffModelMatrixRotate, modelMatrix.get()); 1161 | 1162 | var sff = timeObjects.EqualizerSceneDisplayFirefoxScale.value; 1163 | var scaleff = osg.Matrix.makeScale(sff, sff ,sff, []); 1164 | osg.Matrix.preMult(modelMatrix.get(), scaleff); 1165 | modelMatrix.dirty(); 1166 | 1167 | 1168 | } else { 1169 | //osg.log(audioSound.currentTime + " " +); 1170 | 1171 | if (timeObjects.IntroScene.value > 0.5) { 1172 | uniformIntroTextScene.get()[0] = 1.0; uniformIntroTextScene.dirty(); 1173 | uniformWindIntro.get()[0] = timeObjects.WindIntro.value; uniformWindIntro.dirty(); 1174 | if (timeObjects.Text4.value > 0.0) { 1175 | this.physics.root.getOrCreateStateSet().setTextureAttributeAndMode(6, textureFR, osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1176 | var vec = [0,0,0]; 1177 | vec[timeObjects.Text4.axis] = timeObjects.Text4.axisDirection; 1178 | osg.Matrix.makeRotate((1.0-timeObjects.Text4.value)*0.02, vec[0],vec[1],vec[2], modelMatrix.get()); 1179 | } else if (timeObjects.Text3.value > 0.0) { 1180 | this.physics.root.getOrCreateStateSet().setTextureAttributeAndMode(6, textureSY, osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1181 | var vec = [0,0,0]; 1182 | vec[timeObjects.Text3.axis] = timeObjects.Text3.axisDirection; 1183 | osg.Matrix.makeRotate((1.0-timeObjects.Text3.value)*0.02, vec[0],vec[1],vec[2], modelMatrix.get()); 1184 | } else if (timeObjects.Text2.value > 0.0) { 1185 | this.physics.root.getOrCreateStateSet().setTextureAttributeAndMode(6, textureBy, osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1186 | var vec = [0,0,0]; 1187 | vec[timeObjects.Text2.axis] = timeObjects.Text2.axisDirection; 1188 | osg.Matrix.makeRotate((1.0-timeObjects.Text2.value)*0.02, vec[0],vec[1],vec[2], modelMatrix.get()); 1189 | } else if (timeObjects.Text1.value > 0.0) { 1190 | this.physics.root.getOrCreateStateSet().setTextureAttributeAndMode(6, textureTitle, osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 1191 | 1192 | var vec = [0,0,0]; 1193 | vec[timeObjects.Text1.axis] = timeObjects.Text1.axisDirection; 1194 | 1195 | osg.Matrix.makeRotate((1.0-timeObjects.Text1.value)*0.02, vec[0],vec[1],vec[2], modelMatrix.get()); 1196 | } 1197 | 1198 | weightDistanceMap.set([0.8]); 1199 | freeze.set([timeObjects.FreezeText.value]); 1200 | //osg.log(audioSound.currentTime + " " + timeObjects.FreezeText.value); 1201 | rotationX.set([0.4]); 1202 | 1203 | modelMatrix.dirty(); 1204 | } 1205 | } 1206 | } 1207 | 1208 | this.physics.switchBuffer(); 1209 | this.render.setDisplayTexture( this.physics.getDisplayTexture() ); 1210 | 1211 | this.nbUpdate += 1; 1212 | node.traverse(nv); 1213 | } 1214 | }; 1215 | 1216 | root.setUpdateCallback(new UpdateCallback(physics, render)); 1217 | 1218 | 1219 | //physics.root.setNodeMask(0); 1220 | 1221 | root.addChild(physics.root); 1222 | root.addChild(render.root); 1223 | 1224 | return root; 1225 | 1226 | }; 1227 | -------------------------------------------------------------------------------- /js/text.js: -------------------------------------------------------------------------------- 1 | /** -*- compile-command: "jslint-cli text.js" -*- */ 2 | 3 | var getOrCreateTextShader = function() { 4 | if (!getOrCreateTextShader.shader) { 5 | var vertex = [ 6 | "", 7 | "#ifdef GL_ES", 8 | "precision highp float;", 9 | "#endif", 10 | "attribute vec3 Vertex;", 11 | "attribute vec2 TexCoord0;", 12 | "uniform mat4 ModelViewMatrix;", 13 | "uniform mat4 ProjectionMatrix;", 14 | "varying vec2 uv0;", 15 | "void main(void) {", 16 | " gl_Position = ProjectionMatrix * ModelViewMatrix * vec4(Vertex,1.0);", 17 | " uv0 = TexCoord0;", 18 | "}", 19 | "" 20 | ].join('\n'); 21 | 22 | var fragment = [ 23 | "", 24 | "#ifdef GL_ES", 25 | "precision highp float;", 26 | "#endif", 27 | "varying vec2 uv0;", 28 | "uniform sampler2D Texture0;", 29 | "void main(void) {", 30 | "vec4 color = texture2D(Texture0, uv0);", 31 | "color[0] *= color.w;", 32 | "color[1] *= color.w;", 33 | "color[2] *= color.w;", 34 | "gl_FragColor = color;", 35 | "}", 36 | "" 37 | ].join('\n'); 38 | 39 | var program = new osg.Program( 40 | new osg.Shader(gl.VERTEX_SHADER, vertex), 41 | new osg.Shader(gl.FRAGMENT_SHADER, fragment)); 42 | 43 | getOrCreateTextShader.shader = program; 44 | } 45 | 46 | return getOrCreateTextShader.shader; 47 | }; 48 | 49 | var createTextBlur = function (text, position, color) { 50 | 51 | var setShadow = function(ctx, color, ox, oy, blur) { 52 | ctx.shadowColor = color; 53 | ctx.shadowOffsetX = ox; 54 | ctx.shadowOffsetY = oy; 55 | ctx.shadowBlur = blur; 56 | }; 57 | 58 | if (!position) { 59 | position = [ 0, 0, 0]; 60 | } 61 | 62 | if (!color) { 63 | color = "rgba( 0, 0, 0, 1.0)"; 64 | } 65 | var w,h; 66 | w = 1024; 67 | h = 256; 68 | 69 | var canvas = document.createElement('canvas'); 70 | document.getElementById('View').appendChild(canvas); 71 | canvas.setAttribute('width', w); 72 | canvas.setAttribute('height', h); 73 | 74 | 75 | var ctx = canvas.getContext('2d'); 76 | //ctx.globalAlpha = 0.1; 77 | //ctx.globalAlpha = 0.5; 78 | ctx.fillStyle = color; 79 | //ctx.fillStyle = "rgba(0,0,0,0.0)"; 80 | ctx.font = h + "px sans-serif"; 81 | setShadow(ctx, color, 0,0,20); 82 | ctx.fillText(text, 0 , h-20); 83 | //ctx.strokeText(text, 0 , h-20); 84 | //ctx.shadowOffsetX = 40; 85 | //ctx.shadowOffsetY = -40; 86 | //ctx.shadowColor = "rgb(255,0,0)"; 87 | //ctx.shadowBlur = 2000; 88 | var size = ctx.measureText(text).width; 89 | var ratio = h/w; 90 | var stop = size/w; 91 | osg.log(" size " + size + " quad " + stop); 92 | var quad = osg.createTexturedQuad(position[0], position[1], position[2], 93 | stop, 0, 0, 94 | 0, 0, ratio); 95 | //quad.getOrCreateStateSet().setAttributeAndMode(getOrCreateTextShader()); 96 | var uvs = quad.getAttributes().TexCoord0 97 | for (var i = 0, l = uvs.getElements().length/2; i < l; i++) { 98 | uvs.getElements()[i*2] *= stop; 99 | } 100 | delete quad.getAttributes().Normal; 101 | uvs.dirty(); 102 | 103 | quad.size = size/w; 104 | quad.height = ratio; 105 | var texture = osg.Texture.createFromCanvas(canvas); 106 | texture.setMinFilter("LINEAR_MIPMAP_LINEAR"); 107 | quad.getOrCreateStateSet().setTextureAttributeAndMode(0, texture); 108 | return quad; 109 | }; 110 | 111 | 112 | var createText = function (text, position, color) { 113 | if (!position) { 114 | position = [ 0, 0, 0]; 115 | } 116 | 117 | if (!color) { 118 | color = "rgba( 0, 0, 0, 1.0)"; 119 | } 120 | var w,h; 121 | w = 1024; 122 | h = 256; 123 | 124 | var canvas = document.createElement('canvas'); 125 | canvas.setAttribute('width', w); 126 | canvas.setAttribute('height', h); 127 | 128 | 129 | var ctx = canvas.getContext('2d'); 130 | ctx.fillStyle = color; 131 | ctx.font = h + "px sans-serif"; 132 | ctx.fillText(text, 0 , h-20); 133 | var size = ctx.measureText(text).width; 134 | var ratio = h/w; 135 | var stop = size/w; 136 | osg.log(" size " + size + " quad " + stop); 137 | var quad = osg.createTexturedQuad(position[0], position[1], position[2], 138 | stop, 0, 0, 139 | 0, 0, ratio); 140 | //quad.getOrCreateStateSet().setAttributeAndMode(getOrCreateTextShader()); 141 | var uvs = quad.getAttributes().TexCoord0 142 | for (var i = 0, l = uvs.getElements().length/2; i < l; i++) { 143 | uvs.getElements()[i*2] *= stop; 144 | } 145 | delete quad.getAttributes().Normal; 146 | uvs.dirty(); 147 | 148 | quad.size = size/w; 149 | quad.height = ratio; 150 | var texture = osg.Texture.createFromCanvas(canvas); 151 | texture.setMinFilter("LINEAR_MIPMAP_LINEAR"); 152 | quad.getOrCreateStateSet().setTextureAttributeAndMode(0, texture); 153 | return quad; 154 | }; 155 | 156 | var createTransfrom = function (quad) { 157 | var tr = new osg.MatrixTransform(); 158 | var rotate = osg.Matrix.makeRotate(Math.PI/2 * 0, 0, 1, 0); 159 | var translate = osg.Matrix.makeTranslate(quad.size , 0, 0); 160 | tr.setMatrix(osg.Matrix.preMult(translate,rotate)); 161 | tr.size = quad.size; 162 | return tr; 163 | }; 164 | 165 | 166 | var getSubPartAnimation = function() { 167 | 168 | 169 | }; 170 | 171 | var createFullText = function() { 172 | var subpartAnimation = new Rotate(); 173 | var matrixAnimation = []; 174 | var grp = new osg.Node(); 175 | var flat = function() { 176 | 177 | var q0 = createText("Demo"); 178 | grp.addChild(q0); 179 | var color = "rgba(255,104,1,1.0)"; 180 | 181 | var q1 = createText("JS", [0,0,0], color); 182 | var rotate = new osg.MatrixTransform(); 183 | var tr = createTransfrom(q0); 184 | rotate.addChild(q1); 185 | rotate.setUpdateCallback(subpartAnimation); 186 | 187 | var startRotation = 0; 188 | var endRotation = -Math.PI/2; 189 | osg.Matrix.makeRotate(startRotation, 0,1,0, matrixAnimation); 190 | rotate.setMatrix(matrixAnimation); 191 | rotate.start = [startRotation, 0, 1,0]; 192 | rotate.end = [endRotation, 0, 1, 0]; 193 | rotate.startTime = 2.90; 194 | rotate.duration = 0.45; 195 | 196 | 197 | tr.addChild(rotate); 198 | grp.addChild(tr); 199 | }; 200 | 201 | 202 | var blur = function() { 203 | var offset = new osg.MatrixTransform(); 204 | var q0 = createTextBlur("Demo"); 205 | offset.addChild(q0); 206 | var color = "rgba(255,104,1,1.0)"; 207 | 208 | var q1 = createTextBlur("JS", [0,0,0], color); 209 | var tr = createTransfrom(q0); 210 | 211 | 212 | tr.addChild(q1); 213 | offset.addChild(tr); 214 | offset.setMatrix(osg.Matrix.makeTranslate(0,0.05,0)); 215 | 216 | grp.addChild(offset); 217 | }; 218 | 219 | //blur(); 220 | flat(); 221 | return grp; 222 | }; 223 | 224 | 225 | var Move = function () { this.result = [];}; 226 | Move.prototype = { 227 | update: function (node, nv) { 228 | 229 | var ratio = 0; 230 | var currentTime = nv.getFrameStamp().getSimulationTime(); 231 | if (node.startTime === undefined) { 232 | node.startTime = currentTime; 233 | if (node.duration === undefined) { 234 | node.duration = 2.0; 235 | } 236 | } 237 | 238 | var dt = currentTime - node.startTime; 239 | if (dt > node.duration || dt < 0) { 240 | node.traverse(nv); 241 | //node.setNodeMask(0); 242 | //node.startTime = currentTime; 243 | return; 244 | } 245 | 246 | ratio = dt/node.duration; 247 | var value = osgAnimation.EaseOutQuad(ratio); 248 | osg.Vec3.lerp(value, node.start, node.end, this.result); 249 | osg.Matrix.makeTranslate(this.result[0], this.result[1], this.result[2], node.getMatrix()); 250 | node.traverse(nv); 251 | } 252 | }; 253 | 254 | 255 | var Rotate = function () { this.result = []}; 256 | Rotate.prototype = { 257 | update: function (node, nv) { 258 | 259 | var ratio = 0; 260 | var currentTime = nv.getFrameStamp().getSimulationTime(); 261 | if (node.startTime === undefined) { 262 | node.startTime = currentTime; 263 | if (node.duration === undefined) { 264 | node.duration = 2.0; 265 | } 266 | } 267 | var dt = currentTime - node.startTime; 268 | if (dt > node.duration || dt < 0) { 269 | node.traverse(nv); 270 | //node.setNodeMask(0); 271 | //node.startTime = currentTime; 272 | return; 273 | } 274 | 275 | ratio = dt/node.duration; 276 | var value = osgAnimation.EaseOutQuad(ratio); 277 | osg.Vec4.lerp(value, node.start, node.end, this.result); 278 | osg.Matrix.makeRotate(this.result[0], this.result[1], this.result[2], this.result[3], node.getMatrix()); 279 | node.traverse(nv); 280 | } 281 | }; 282 | 283 | 284 | var createSceneText = function() { 285 | 286 | var grp = new osg.MatrixTransform(); 287 | grp.getOrCreateStateSet().setAttributeAndMode(new osg.CullFace('DISABLE')); 288 | grp.getOrCreateStateSet().setAttributeAndMode(getOrCreateTextShader(), osg.StateAttribute.ON | osg.StateAttribute.OVERRIDE); 289 | grp.getOrCreateStateSet().setAttributeAndMode(new osg.BlendFunc('ONE', 'ONE_MINUS_SRC_ALPHA')); 290 | 291 | 292 | grp.addChild(createFullText()); 293 | grp.setUpdateCallback(new Move()); 294 | grp.setNodeMask(0); 295 | grp.startTime = 1.60; 296 | grp.start = [10, 0,0]; 297 | grp.end = [0, 0, 0]; 298 | grp.duration = 0.45; 299 | setTimeout(function() { 300 | grp.setNodeMask(1); 301 | }, 1550); 302 | 303 | var mtr = new osg.MatrixTransform(); 304 | mtr.setUpdateCallback(new Rotate()); 305 | var startRotation = Math.PI + Math.PI/2 + Math.PI/4; 306 | var endRotation = Math.PI + Math.PI/2 + Math.PI/2; 307 | osg.Matrix.makeRotate(startRotation, 0,0,1, mtr.getMatrix()); 308 | mtr.start = [startRotation, 0, 0,1]; 309 | mtr.end = [endRotation, 0, 0, 1]; 310 | mtr.startTime = 2.90; 311 | mtr.duration = 0.45; 312 | 313 | mtr.addChild(grp); 314 | return mtr; 315 | 316 | 317 | var q0 = createText("Demo"); 318 | grp.addChild(q0); 319 | var color = "rgba(255,104,1,1.0)"; 320 | 321 | var q1 = createText("JS", [0,0,0], color); 322 | var tr = createTransfrom(q0); 323 | tr.addChild(q1); 324 | grp.addChild(tr); 325 | 326 | 327 | var q0 = createTextBlur("Demo"); 328 | grp.addChild(q0); 329 | var color = "rgba(255,104,1,1.0)"; 330 | 331 | var q1 = createTextBlur("JS", [0,0,0], color); 332 | var tr = createTransfrom(q0); 333 | tr.addChild(q1); 334 | grp.addChild(tr); 335 | 336 | 337 | return grp; 338 | } 339 | -------------------------------------------------------------------------------- /js/time.js: -------------------------------------------------------------------------------- 1 | var timeEvents = [ 2 | { 3 | "Event": "FRQMusicRiff", 4 | "Note": "Note F0", 5 | "Time": "00.014" 6 | }, 7 | { 8 | "Event": "FRQMusicSound1", 9 | "Note": "Note A0", 10 | "Time": "00.015" 11 | }, 12 | { 13 | "Event": "FRQMusicSound2", 14 | "Note": "Note B0", 15 | "Time": "00.920" 16 | }, 17 | { 18 | "Event": "FRQMusicSound3", 19 | "Note": "Note C1", 20 | "Time": "01.841" 21 | }, 22 | { 23 | "Event": "FRQMusicSound1", 24 | "Note": "Note A0", 25 | "Time": "03.690" 26 | }, 27 | { 28 | "Event": "FRQMusicSound2", 29 | "Note": "Note B0", 30 | "Time": "04.610" 31 | }, 32 | { 33 | "Event": "FRQMusicSound3", 34 | "Note": "Note C1", 35 | "Time": "05.540" 36 | }, 37 | { 38 | "Event": "FRQMusicChangePattern", 39 | "Note": "Note G0", 40 | "Time": "07.380" 41 | }, 42 | { 43 | "Event": "FRQMusicRiff", 44 | "Note": "Note F0", 45 | "Time": "07.397" 46 | }, 47 | { 48 | "Event": "FRQMusicSound1", 49 | "Note": "Note A0", 50 | "Time": "07.417" 51 | }, 52 | { 53 | "Event": "FRQMusicSound2", 54 | "Note": "Note B0", 55 | "Time": "08.302" 56 | }, 57 | { 58 | "Event": "FRQMusicSound3", 59 | "Note": "Note C1", 60 | "Time": "09.221" 61 | }, 62 | { 63 | "Event": "FRQMusicRiff", 64 | "Note": "Note F0", 65 | "Time": "11.070" 66 | }, 67 | { 68 | "Event": "FRQMusicSound1", 69 | "Note": "Note A0", 70 | "Time": "11.076" 71 | }, 72 | { 73 | "Event": "FRQMusicSound2", 74 | "Note": "Note B0", 75 | "Time": "12.000" 76 | }, 77 | { 78 | "Event": "FRQMusicSound3", 79 | "Note": "Note C1", 80 | "Time": "12.921" 81 | }, 82 | { 83 | "Event": "FRQMusicChangePattern", 84 | "Note": "Note G0", 85 | "Time": "14.764" 86 | }, 87 | { 88 | "Event": "FRQMusicKick", 89 | "Note": "Note D0", 90 | "Time": "14.765" 91 | }, 92 | { 93 | "Event": "FRQMusicRiff", 94 | "Note": "Note F0", 95 | "Time": "14.765" 96 | }, 97 | { 98 | "Event": "FRQMusicSound1", 99 | "Note": "Note A0", 100 | "Time": "14.765" 101 | }, 102 | { 103 | "Event": "FRQMusicSnare", 104 | "Note": "Note E0", 105 | "Time": "15.223" 106 | }, 107 | { 108 | "Event": "FRQMusicKick", 109 | "Note": "Note D0", 110 | "Time": "15.691" 111 | }, 112 | { 113 | "Event": "FRQMusicSound2", 114 | "Note": "Note B0", 115 | "Time": "15.705" 116 | }, 117 | { 118 | "Event": "FRQMusicSnare", 119 | "Note": "Note E0", 120 | "Time": "16.151" 121 | }, 122 | { 123 | "Event": "FRQMusicKick", 124 | "Note": "Note D0", 125 | "Time": "16.611" 126 | }, 127 | { 128 | "Event": "FRQMusicSound3", 129 | "Note": "Note C1", 130 | "Time": "16.626" 131 | }, 132 | { 133 | "Event": "FRQMusicSnare", 134 | "Note": "Note E0", 135 | "Time": "17.071" 136 | }, 137 | { 138 | "Event": "FRQMusicKick", 139 | "Note": "Note D0", 140 | "Time": "17.543" 141 | }, 142 | { 143 | "Event": "FRQMusicSnare", 144 | "Note": "Note E0", 145 | "Time": "18.003" 146 | }, 147 | { 148 | "Event": "FRQMusicKick", 149 | "Note": "Note D0", 150 | "Time": "18.463" 151 | }, 152 | { 153 | "Event": "FRQMusicRiff", 154 | "Note": "Note F0", 155 | "Time": "18.467" 156 | }, 157 | { 158 | "Event": "FRQMusicSound1", 159 | "Note": "Note A0", 160 | "Time": "18.487" 161 | }, 162 | { 163 | "Event": "FRQMusicSnare", 164 | "Note": "Note E0", 165 | "Time": "18.923" 166 | }, 167 | { 168 | "Event": "FRQMusicKick", 169 | "Note": "Note D0", 170 | "Time": "19.383" 171 | }, 172 | { 173 | "Event": "FRQMusicSound2", 174 | "Note": "Note B0", 175 | "Time": "19.387" 176 | }, 177 | { 178 | "Event": "FRQMusicSnare", 179 | "Note": "Note E0", 180 | "Time": "19.846" 181 | }, 182 | { 183 | "Event": "FRQMusicKick", 184 | "Note": "Note D0", 185 | "Time": "20.306" 186 | }, 187 | { 188 | "Event": "FRQMusicSound3", 189 | "Note": "Note C1", 190 | "Time": "20.308" 191 | }, 192 | { 193 | "Event": "FRQMusicSnare", 194 | "Note": "Note E0", 195 | "Time": "20.766" 196 | }, 197 | { 198 | "Event": "FRQMusicKick", 199 | "Note": "Note D0", 200 | "Time": "21.226" 201 | }, 202 | { 203 | "Event": "FRQMusicSnare", 204 | "Note": "Note E0", 205 | "Time": "21.694" 206 | }, 207 | { 208 | "Event": "FRQMusicChangePattern", 209 | "Note": "Note G0", 210 | "Time": "22.154" 211 | }, 212 | { 213 | "Event": "FRQMusicKick", 214 | "Note": "Note D0", 215 | "Time": "22.170" 216 | }, 217 | { 218 | "Event": "FRQMusicRiff", 219 | "Note": "Note F0", 220 | "Time": "22.171" 221 | }, 222 | { 223 | "Event": "FRQMusicSound1", 224 | "Note": "Note A0", 225 | "Time": "22.172" 226 | }, 227 | { 228 | "Event": "FRQMusicSnare", 229 | "Note": "Note E0", 230 | "Time": "22.614" 231 | }, 232 | { 233 | "Event": "FRQMusicSynth", 234 | "Note": "Note E1", 235 | "Time": "22.629" 236 | }, 237 | { 238 | "Event": "FRQMusicKick", 239 | "Note": "Note D0", 240 | "Time": "23.074" 241 | }, 242 | { 243 | "Event": "FRQMusicSound2", 244 | "Note": "Note B0", 245 | "Time": "23.089" 246 | }, 247 | { 248 | "Event": "FRQMusicSynth", 249 | "Note": "Note E1", 250 | "Time": "23.306" 251 | }, 252 | { 253 | "Event": "FRQMusicKick", 254 | "Note": "Note D0", 255 | "Time": "23.424" 256 | }, 257 | { 258 | "Event": "FRQMusicSnare", 259 | "Note": "Note E0", 260 | "Time": "23.544" 261 | }, 262 | { 263 | "Event": "FRQMusicKick", 264 | "Note": "Note D0", 265 | "Time": "24.004" 266 | }, 267 | { 268 | "Event": "FRQMusicSound3", 269 | "Note": "Note C1", 270 | "Time": "24.009" 271 | }, 272 | { 273 | "Event": "FRQMusicSnare", 274 | "Note": "Note E0", 275 | "Time": "24.464" 276 | }, 277 | { 278 | "Event": "FRQMusicKick", 279 | "Note": "Note D0", 280 | "Time": "24.924" 281 | }, 282 | { 283 | "Event": "FRQMusicSnare", 284 | "Note": "Note E0", 285 | "Time": "25.384" 286 | }, 287 | { 288 | "Event": "FRQMusicKick", 289 | "Note": "Note D0", 290 | "Time": "25.846" 291 | }, 292 | { 293 | "Event": "FRQMusicRiff", 294 | "Note": "Note F0", 295 | "Time": "25.849" 296 | }, 297 | { 298 | "Event": "FRQMusicSound1", 299 | "Note": "Note A0", 300 | "Time": "25.850" 301 | }, 302 | { 303 | "Event": "FRQMusicSnare", 304 | "Note": "Note E0", 305 | "Time": "26.306" 306 | }, 307 | { 308 | "Event": "FRQMusicSynth", 309 | "Note": "Note E1", 310 | "Time": "26.309" 311 | }, 312 | { 313 | "Event": "FRQMusicKick", 314 | "Note": "Note D0", 315 | "Time": "26.766" 316 | }, 317 | { 318 | "Event": "FRQMusicSound2", 319 | "Note": "Note B0", 320 | "Time": "26.769" 321 | }, 322 | { 323 | "Event": "FRQMusicSynth", 324 | "Note": "Note E1", 325 | "Time": "27.004" 326 | }, 327 | { 328 | "Event": "FRQMusicSnare", 329 | "Note": "Note E0", 330 | "Time": "27.226" 331 | }, 332 | { 333 | "Event": "FRQMusicKick", 334 | "Note": "Note D0", 335 | "Time": "27.694" 336 | }, 337 | { 338 | "Event": "FRQMusicSound3", 339 | "Note": "Note C1", 340 | "Time": "27.709" 341 | }, 342 | { 343 | "Event": "FRQMusicSnare", 344 | "Note": "Note E0", 345 | "Time": "28.154" 346 | }, 347 | { 348 | "Event": "FRQMusicKick", 349 | "Note": "Note D0", 350 | "Time": "28.614" 351 | }, 352 | { 353 | "Event": "FRQMusicSnare", 354 | "Note": "Note E0", 355 | "Time": "29.073" 356 | }, 357 | { 358 | "Event": "FRQMusicSynth", 359 | "Note": "Note E1", 360 | "Time": "29.090" 361 | }, 362 | { 363 | "Event": "FRQMusicChangePattern", 364 | "Note": "Note G0", 365 | "Time": "29.537" 366 | }, 367 | { 368 | "Event": "FRQMusicKick", 369 | "Note": "Note D0", 370 | "Time": "29.556" 371 | }, 372 | { 373 | "Event": "FRQMusicRiff", 374 | "Note": "Note F0", 375 | "Time": "29.577" 376 | }, 377 | { 378 | "Event": "FRQMusicVocal", 379 | "Note": "Note D1", 380 | "Time": "29.577" 381 | }, 382 | { 383 | "Event": "FRQMusicSynth", 384 | "Note": "Note E1", 385 | "Time": "29.598" 386 | }, 387 | { 388 | "Event": "FRQMusicKick", 389 | "Note": "Note D0", 390 | "Time": "29.765" 391 | }, 392 | { 393 | "Event": "FRQMusicSnare", 394 | "Note": "Note E0", 395 | "Time": "30.000" 396 | }, 397 | { 398 | "Event": "FRQMusicKick", 399 | "Note": "Note D0", 400 | "Time": "30.226" 401 | }, 402 | { 403 | "Event": "FRQMusicKick", 404 | "Note": "Note D0", 405 | "Time": "30.462" 406 | }, 407 | { 408 | "Event": "FRQMusicVocal", 409 | "Note": "Note D1", 410 | "Time": "30.476" 411 | }, 412 | { 413 | "Event": "FRQMusicSnare", 414 | "Note": "Note E0", 415 | "Time": "30.919" 416 | }, 417 | { 418 | "Event": "FRQMusicKick", 419 | "Note": "Note D0", 420 | "Time": "31.378" 421 | }, 422 | { 423 | "Event": "FRQMusicVocal", 424 | "Note": "Note D1", 425 | "Time": "31.392" 426 | }, 427 | { 428 | "Event": "FRQMusicSynth", 429 | "Note": "Note E1", 430 | "Time": "31.393" 431 | }, 432 | { 433 | "Event": "FRQMusicSnare", 434 | "Note": "Note E0", 435 | "Time": "31.847" 436 | }, 437 | { 438 | "Event": "FRQMusicVocal", 439 | "Note": "Note D1", 440 | "Time": "32.073" 441 | }, 442 | { 443 | "Event": "FRQMusicKick", 444 | "Note": "Note D0", 445 | "Time": "32.307" 446 | }, 447 | { 448 | "Event": "FRQMusicSnare", 449 | "Note": "Note E0", 450 | "Time": "32.757" 451 | }, 452 | { 453 | "Event": "FRQMusicKick", 454 | "Note": "Note D0", 455 | "Time": "33.217" 456 | }, 457 | { 458 | "Event": "FRQMusicRiff", 459 | "Note": "Note F0", 460 | "Time": "33.230" 461 | }, 462 | { 463 | "Event": "FRQMusicSnare", 464 | "Note": "Note E0", 465 | "Time": "33.685" 466 | }, 467 | { 468 | "Event": "FRQMusicKick", 469 | "Note": "Note D0", 470 | "Time": "34.145" 471 | }, 472 | { 473 | "Event": "FRQMusicVocal", 474 | "Note": "Note D1", 475 | "Time": "34.150" 476 | }, 477 | { 478 | "Event": "FRQMusicSnare", 479 | "Note": "Note E0", 480 | "Time": "34.605" 481 | }, 482 | { 483 | "Event": "FRQMusicSynth", 484 | "Note": "Note E1", 485 | "Time": "34.609" 486 | }, 487 | { 488 | "Event": "FRQMusicKick", 489 | "Note": "Note D0", 490 | "Time": "35.065" 491 | }, 492 | { 493 | "Event": "FRQMusicSynth", 494 | "Note": "Note E1", 495 | "Time": "35.070" 496 | }, 497 | { 498 | "Event": "FRQMusicSnare", 499 | "Note": "Note E0", 500 | "Time": "35.535" 501 | }, 502 | { 503 | "Event": "FRQMusicKick", 504 | "Note": "Note D0", 505 | "Time": "35.995" 506 | }, 507 | { 508 | "Event": "FRQMusicSnare", 509 | "Note": "Note E0", 510 | "Time": "36.455" 511 | }, 512 | { 513 | "Event": "FRQMusicChangePattern", 514 | "Note": "Note G0", 515 | "Time": "36.915" 516 | }, 517 | { 518 | "Event": "FRQMusicKick", 519 | "Note": "Note D0", 520 | "Time": "36.931" 521 | }, 522 | { 523 | "Event": "FRQMusicSynth", 524 | "Note": "Note E1", 525 | "Time": "36.931" 526 | }, 527 | { 528 | "Event": "FRQMusicSnare", 529 | "Note": "Note E0", 530 | "Time": "37.375" 531 | }, 532 | { 533 | "Event": "FRQMusicSynth", 534 | "Note": "Note E1", 535 | "Time": "37.605" 536 | }, 537 | { 538 | "Event": "FRQMusicKick", 539 | "Note": "Note D0", 540 | "Time": "37.837" 541 | }, 542 | { 543 | "Event": "FRQMusicSnare", 544 | "Note": "Note E0", 545 | "Time": "38.297" 546 | }, 547 | { 548 | "Event": "FRQMusicKick", 549 | "Note": "Note D0", 550 | "Time": "38.757" 551 | }, 552 | { 553 | "Event": "FRQMusicSynth", 554 | "Note": "Note E1", 555 | "Time": "38.770" 556 | }, 557 | { 558 | "Event": "FRQMusicSnare", 559 | "Note": "Note E0", 560 | "Time": "39.217" 561 | }, 562 | { 563 | "Event": "FRQMusicKick", 564 | "Note": "Note D0", 565 | "Time": "39.695" 566 | }, 567 | { 568 | "Event": "FRQMusicSnare", 569 | "Note": "Note E0", 570 | "Time": "40.155" 571 | }, 572 | { 573 | "Event": "FRQMusicSynth", 574 | "Note": "Note E1", 575 | "Time": "40.170" 576 | }, 577 | { 578 | "Event": "FRQMusicSnare", 579 | "Note": "Note E0", 580 | "Time": "40.495" 581 | }, 582 | { 583 | "Event": "FRQMusicKick", 584 | "Note": "Note D0", 585 | "Time": "40.605" 586 | }, 587 | { 588 | "Event": "FRQMusicSynth", 589 | "Note": "Note E1", 590 | "Time": "40.610" 591 | }, 592 | { 593 | "Event": "FRQMusicSnare", 594 | "Note": "Note E0", 595 | "Time": "41.065" 596 | }, 597 | { 598 | "Event": "FRQMusicKick", 599 | "Note": "Note D0", 600 | "Time": "41.535" 601 | }, 602 | { 603 | "Event": "FRQMusicSynth", 604 | "Note": "Note E1", 605 | "Time": "41.550" 606 | }, 607 | { 608 | "Event": "FRQMusicSnare", 609 | "Note": "Note E0", 610 | "Time": "41.995" 611 | }, 612 | { 613 | "Event": "FRQMusicKick", 614 | "Note": "Note D0", 615 | "Time": "42.455" 616 | }, 617 | { 618 | "Event": "FRQMusicSynth", 619 | "Note": "Note E1", 620 | "Time": "42.470" 621 | }, 622 | { 623 | "Event": "FRQMusicSnare", 624 | "Note": "Note E0", 625 | "Time": "42.915" 626 | }, 627 | { 628 | "Event": "FRQMusicKick", 629 | "Note": "Note D0", 630 | "Time": "43.257" 631 | }, 632 | { 633 | "Event": "FRQMusicKick", 634 | "Note": "Note D0", 635 | "Time": "43.605" 636 | }, 637 | { 638 | "Event": "FRQMusicSnare", 639 | "Note": "Note E0", 640 | "Time": "43.837" 641 | }, 642 | { 643 | "Event": "FRQMusicKick", 644 | "Note": "Note D0", 645 | "Time": "44.065" 646 | }, 647 | { 648 | "Event": "FRQMusicChangePattern", 649 | "Note": "Note G0", 650 | "Time": "44.297" 651 | }, 652 | { 653 | "Event": "FRQMusicKick", 654 | "Note": "Note D0", 655 | "Time": "44.311" 656 | }, 657 | { 658 | "Event": "FRQMusicSynth", 659 | "Note": "Note E1", 660 | "Time": "44.311" 661 | }, 662 | { 663 | "Event": "FRQMusicSnare", 664 | "Note": "Note E0", 665 | "Time": "44.758" 666 | }, 667 | { 668 | "Event": "FRQMusicSynth", 669 | "Note": "Note E1", 670 | "Time": "44.996" 671 | }, 672 | { 673 | "Event": "FRQMusicKick", 674 | "Note": "Note D0", 675 | "Time": "45.218" 676 | }, 677 | { 678 | "Event": "FRQMusicKick", 679 | "Note": "Note D0", 680 | "Time": "45.566" 681 | }, 682 | { 683 | "Event": "FRQMusicSnare", 684 | "Note": "Note E0", 685 | "Time": "45.686" 686 | }, 687 | { 688 | "Event": "FRQMusicKick", 689 | "Note": "Note D0", 690 | "Time": "46.146" 691 | }, 692 | { 693 | "Event": "FRQMusicSynth", 694 | "Note": "Note E1", 695 | "Time": "46.150" 696 | }, 697 | { 698 | "Event": "FRQMusicSnare", 699 | "Note": "Note E0", 700 | "Time": "46.606" 701 | }, 702 | { 703 | "Event": "FRQMusicKick", 704 | "Note": "Note D0", 705 | "Time": "47.067" 706 | }, 707 | { 708 | "Event": "FRQMusicSnare", 709 | "Note": "Note E0", 710 | "Time": "47.539" 711 | }, 712 | { 713 | "Event": "FRQMusicSynth", 714 | "Note": "Note E1", 715 | "Time": "47.540" 716 | }, 717 | { 718 | "Event": "FRQMusicKick", 719 | "Note": "Note D0", 720 | "Time": "48.002" 721 | }, 722 | { 723 | "Event": "FRQMusicSynth", 724 | "Note": "Note E1", 725 | "Time": "48.008" 726 | }, 727 | { 728 | "Event": "FRQMusicSnare", 729 | "Note": "Note E0", 730 | "Time": "48.461" 731 | }, 732 | { 733 | "Event": "FRQMusicKick", 734 | "Note": "Note D0", 735 | "Time": "48.922" 736 | }, 737 | { 738 | "Event": "FRQMusicSynth", 739 | "Note": "Note E1", 740 | "Time": "48.937" 741 | }, 742 | { 743 | "Event": "FRQMusicSnare", 744 | "Note": "Note E0", 745 | "Time": "49.382" 746 | }, 747 | { 748 | "Event": "FRQMusicKick", 749 | "Note": "Note D0", 750 | "Time": "49.844" 751 | }, 752 | { 753 | "Event": "FRQMusicSynth", 754 | "Note": "Note E1", 755 | "Time": "49.855" 756 | }, 757 | { 758 | "Event": "FRQMusicSnare", 759 | "Note": "Note E0", 760 | "Time": "50.304" 761 | }, 762 | { 763 | "Event": "FRQMusicKick", 764 | "Note": "Note D0", 765 | "Time": "50.764" 766 | }, 767 | { 768 | "Event": "FRQMusicSnare", 769 | "Note": "Note E0", 770 | "Time": "51.224" 771 | }, 772 | { 773 | "Event": "FRQMusicChangePattern", 774 | "Note": "Note G0", 775 | "Time": "51.694" 776 | }, 777 | { 778 | "Event": "FRQMusicKick", 779 | "Note": "Note D0", 780 | "Time": "51.697" 781 | }, 782 | { 783 | "Event": "FRQMusicSound1", 784 | "Note": "Note A0", 785 | "Time": "51.717" 786 | }, 787 | { 788 | "Event": "FRQMusicSynth", 789 | "Note": "Note E1", 790 | "Time": "51.737" 791 | }, 792 | { 793 | "Event": "FRQMusicKick", 794 | "Note": "Note D0", 795 | "Time": "52.146" 796 | }, 797 | { 798 | "Event": "FRQMusicSnare", 799 | "Note": "Note E0", 800 | "Time": "52.158" 801 | }, 802 | { 803 | "Event": "FRQMusicSound2", 804 | "Note": "Note B0", 805 | "Time": "52.606" 806 | }, 807 | {} 808 | ]; 809 | -------------------------------------------------------------------------------- /js/timefunction.js: -------------------------------------------------------------------------------- 1 | /** -*- compile-command: "jslint-cli timefunction.js" -*- 2 | * 3 | * Copyright (C) 2011 Cedric Pinson 4 | * 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | * Authors: 21 | * Cedric Pinson 22 | * 23 | */ 24 | 25 | var setEqualizerCameraPosition; 26 | var changeModel; 27 | 28 | var timeSetup = function(eventData) { 29 | var dictObject = {}; 30 | 31 | eventData.push( { 32 | "Event": "RotationZ", 33 | "Note": "", 34 | "Time": "00.018" 35 | }); 36 | 37 | eventData.push( { 38 | "Event": "RotationZ", 39 | "Note": "", 40 | "Time": "00.418" 41 | }); 42 | 43 | eventData.push( { 44 | "Event": "RotationZ", 45 | "Note": "", 46 | "Time": "00.918" 47 | }); 48 | 49 | 50 | duration = { "FRQMusicSnare": 51 | { 52 | "start": 0.1, 53 | "stay": 0.0001, 54 | "end": 0.1 55 | }, 56 | "FRQMusicKick": 57 | { 58 | "start": 0.1, 59 | "stay": 0.0001, 60 | "end": 0.1 61 | }, 62 | "FRQMusicVocal": 63 | { 64 | "start": 0.1, 65 | "stay": 0.0001, 66 | "end": 0.1, 67 | "func": changeModel 68 | }, 69 | "FRQMusicSound1": 70 | { 71 | "offset": 0.3, 72 | "start": 0.2, 73 | "stay": 0.3, 74 | "end": 0.4 75 | }, 76 | "FRQMusicSound2": 77 | { 78 | "offset": 0.3, 79 | "start": 0.2, 80 | "stay": 0.3, 81 | "end": 0.4 82 | }, 83 | "FRQMusicSound3": 84 | { 85 | "offset": 0.3, 86 | "start": 0.2, 87 | "stay": 0.3, 88 | "end": 0.4 89 | }, 90 | 91 | "FRQMusicSynth": 92 | { 93 | "offset": 0.3, 94 | "start": 0.2, 95 | "stay": 0.4, 96 | "end": 1.2 97 | }, 98 | }; 99 | 100 | 101 | 102 | for (var i = 0, l = eventData.length; i < l; i++) { 103 | var event = eventData[i]; 104 | if (!event.Event) { 105 | continue; 106 | } 107 | var eventName = event.Event; 108 | var time = parseFloat(event.Time); 109 | var note = event.Note; 110 | if (!dictObject[eventName]) { 111 | var obj = {}; 112 | 113 | obj.name = eventName; 114 | obj.value = 0.0; 115 | obj.note = note; 116 | dictObject[eventName] = obj; 117 | } 118 | 119 | var start = 0.0001; 120 | var stay = 0.5; 121 | var end = 0.1; 122 | var offset = 0.0; 123 | var func = undefined; 124 | if (duration[eventName] !== undefined) { 125 | start = duration[eventName].start; 126 | stay = duration[eventName].stay; 127 | end = duration[eventName].end; 128 | func = duration[eventName].func; 129 | if (duration[eventName].offset !== undefined) { 130 | offset = duration[eventName].offset; 131 | } 132 | } 133 | anim(eventName,dictObject[eventName]).to( time-start + offset, 134 | { value:1.0 }, 135 | func, 136 | start, 137 | Timeline.Easing.Linear.EaseNone 138 | ).to( 139 | stay, 140 | { value:0.0}, 141 | end, 142 | //Timeline.Easing.Cubic.EaseOut 143 | Timeline.Easing.Linear.EaseNone 144 | ); 145 | } 146 | 147 | 148 | var axisOrder = [ 0, 2 ,1, 149 | 2, 0, 1, 150 | 0, 2, 1, 151 | 2, 0, 1]; 152 | var axisIndex = 0; 153 | var selectAxis = function() { 154 | this.axis = axisOrder[axisIndex++]; 155 | this.axisDirection = 1; 156 | if (0.5 - Math.random() < 0.0) { 157 | this.axisDirection = -1; 158 | } 159 | }; 160 | 161 | 162 | dictObject.FreezeText = { value: 0.0}; 163 | anim("FreezeText", dictObject.FreezeText).to( 164 | 0.021, 165 | { value:1.0 }, 166 | 0.0001, 167 | Timeline.Easing.Linear.EaseNone 168 | ).to( 169 | 0.5, 170 | { value:0.0}, 171 | 0.1 172 | ); 173 | anim("FreezeText", dictObject.FreezeText).to( 174 | 3.75, 175 | { value:1.0 }, 176 | 0.0001, 177 | Timeline.Easing.Linear.EaseNone 178 | ).to( 179 | 0.5, 180 | { value:0.0}, 181 | 0.1 182 | ); 183 | anim("FreezeText", dictObject.FreezeText).to( 184 | 7.4, 185 | { value:1.0 }, 186 | 0.0001, 187 | Timeline.Easing.Linear.EaseNone 188 | ).to( 189 | 0.5, 190 | { value:0.0}, 191 | 0.1 192 | ); 193 | anim("FreezeText", dictObject.FreezeText).to( 194 | 11.1, 195 | { value:1.0 }, 196 | 0.0001, 197 | Timeline.Easing.Linear.EaseNone 198 | ).to( 199 | 0.5, 200 | { value:0.0}, 201 | 0.1 202 | ); 203 | 204 | 205 | dictObject.WindIntro = { value: 0.0}; 206 | var windStartValue = 6.0; 207 | var windWaitValue = 0.5; 208 | var windDurationRestore = 0.2; 209 | var windEndValue = 0.5; 210 | anim("WindIntro",dictObject.WindIntro).to( 211 | 0.02, 212 | { value: windStartValue }, 213 | 0.000001, 214 | Timeline.Easing.Cubic.EaseIn 215 | ).to( 216 | windWaitValue, 217 | { value: windEndValue}, 218 | windDurationRestore 219 | ); 220 | anim("WindIntro",dictObject.WindIntro).to( 221 | 3.75, 222 | { value: windStartValue }, 223 | 0.000001, 224 | Timeline.Easing.Cubic.EaseIn 225 | ).to( 226 | windWaitValue, 227 | { value:windEndValue}, 228 | windDurationRestore 229 | ); 230 | anim("WindIntro",dictObject.WindIntro).to( 231 | 7.45, 232 | { value: windStartValue }, 233 | 0.000001, 234 | Timeline.Easing.Cubic.EaseIn 235 | ).to( 236 | windWaitValue, 237 | { value: windEndValue}, 238 | windDurationRestore 239 | ); 240 | anim("WindIntro",dictObject.WindIntro).to( 241 | 11.1, 242 | { value: windStartValue }, 243 | 0.000001, 244 | Timeline.Easing.Cubic.EaseIn 245 | ).to( 246 | windWaitValue, 247 | { value: windEndValue}, 248 | windDurationRestore 249 | ); 250 | 251 | 252 | dictObject.StateText = { value: 0.0}; 253 | anim("StateText",dictObject.StateText).to( 254 | 0.02, 255 | { value: 1.0}, 256 | 0.00001 257 | ); 258 | anim("StateText",dictObject.StateText).to( 259 | 3.75, 260 | { value: 2.0}, 261 | 0.00001 262 | ); 263 | anim("StateText",dictObject.StateText).to( 264 | 7.40, 265 | { value: 3.0}, 266 | 0.00001 267 | ); 268 | anim("StateText",dictObject.StateText).to( 269 | 11.1, 270 | { value: 4.0}, 271 | 0.00001 272 | ); 273 | 274 | 275 | dictObject.Text1 = { value: 0.0}; 276 | anim("Text1",dictObject.Text1).to( 277 | 0.02, 278 | { value:1.0 }, 279 | selectAxis, 280 | 0.1, 281 | Timeline.Easing.Cubic.EaseIn 282 | ).to( 283 | 0.0, 284 | { value:0.0}, 285 | 0.00001 286 | ).to( 287 | 0.8, 288 | { value:1.0 }, 289 | selectAxis, 290 | 0.1, 291 | Timeline.Easing.Cubic.EaseIn 292 | ).to( 293 | { value:0.0}, 294 | 0.00001 295 | ).to( 296 | 0.8, 297 | { value:1.0 }, 298 | selectAxis, 299 | 0.1, 300 | Timeline.Easing.Cubic.EaseIn 301 | ).to( 302 | { value:0.0}, 303 | 0.00001 304 | ); 305 | 306 | 307 | dictObject.Text2 = { value: 0.0}; 308 | anim("Text2",dictObject.Text2).to( 309 | 3.75, 310 | { value:1.0 }, 311 | selectAxis, 312 | 0.1, 313 | Timeline.Easing.Cubic.EaseIn 314 | ).to( 315 | 0.0, 316 | { value:0.0}, 317 | 0.00001 318 | ).to( 319 | 0.8, 320 | { value:1.0 }, 321 | selectAxis, 322 | 0.1, 323 | Timeline.Easing.Cubic.EaseIn 324 | ).to( 325 | { value:0.0}, 326 | 0.00001 327 | ).to( 328 | 0.8, 329 | { value:1.0 }, 330 | selectAxis, 331 | 0.1, 332 | Timeline.Easing.Cubic.EaseIn 333 | ).to( 334 | { value:0.0}, 335 | 0.00001 336 | ); 337 | 338 | 339 | dictObject.Text3 = { value: 0.0}; 340 | anim("Text3",dictObject.Text3).to( 341 | 7.40, 342 | { value:1.0 }, 343 | selectAxis, 344 | 0.1, 345 | Timeline.Easing.Cubic.EaseIn 346 | ).to( 347 | 0.0, 348 | { value:0.0}, 349 | 0.00001 350 | ).to( 351 | 0.8, 352 | { value:1.0 }, 353 | selectAxis, 354 | 0.1, 355 | Timeline.Easing.Cubic.EaseIn 356 | ).to( 357 | { value:0.0}, 358 | 0.00001 359 | ).to( 360 | 0.8, 361 | { value:1.0 }, 362 | selectAxis, 363 | 0.1, 364 | Timeline.Easing.Cubic.EaseIn 365 | ).to( 366 | { value:0.0}, 367 | 0.00001 368 | ); 369 | 370 | 371 | dictObject.Text4 = { value: 0.0}; 372 | anim("Text4",dictObject.Text4).to( 373 | 11.1, 374 | { value:1.0 }, 375 | selectAxis, 376 | 0.1, 377 | Timeline.Easing.Cubic.EaseIn 378 | ).to( 379 | 0.0, 380 | { value:0.0}, 381 | 0.00001 382 | ).to( 383 | 0.8, 384 | { value:1.0 }, 385 | selectAxis, 386 | 0.1, 387 | Timeline.Easing.Cubic.EaseIn 388 | ).to( 389 | { value:0.0}, 390 | 0.00001 391 | ).to( 392 | 0.8, 393 | { value:1.0 }, 394 | selectAxis, 395 | 0.1, 396 | Timeline.Easing.Cubic.EaseIn 397 | ).to( 398 | { value:0.0}, 399 | 0.00001 400 | ); 401 | 402 | 403 | 404 | 405 | dictObject.IntroScene = { value: 0.0}; 406 | anim("IntroScene",dictObject.IntroScene).to( 407 | 0.0, 408 | { value:1.0 }, 409 | 0.00001, 410 | Timeline.Easing.Linear.None 411 | ).to( 412 | 14.756, 413 | { value:0.0}, 414 | 0.00001 415 | ); 416 | 417 | dictObject.EqualizerScene = { value: 0.0 , timeStart:14.556}; 418 | anim("EqualizerScene",dictObject.EqualizerScene).to( 419 | 14.556, 420 | { value:1.0 }, 421 | setEqualizerCameraPosition, 422 | 0.00001, 423 | Timeline.Easing.Linear.None 424 | ).to( 425 | 59.0, 426 | { value:0.0}, 427 | 0.00001 428 | ); 429 | 430 | dictObject.EqualizerSceneShowModel = { value: 0.0}; 431 | anim("EqualizerSceneShowModel",dictObject.EqualizerSceneShowModel).to( 432 | 22.629-3.0, 433 | { value:1.0 }, 434 | changeModel, // to setup the first model 435 | 5.0, 436 | Timeline.Easing.Linear.None 437 | ).to( 438 | 100.0, 439 | { value:0.0}, 440 | 0.00001 441 | ); 442 | 443 | dictObject.EqualizerSceneDisplayFirefox = { value: 0.0}; 444 | anim("EqualizerSceneDisplayFirefox",dictObject.EqualizerSceneDisplayFirefox).to( 445 | 40.77, 446 | { value:1.0 }, 447 | changeModel, // just to switch the last model 448 | 0.5, 449 | Timeline.Easing.Linear.None 450 | ).to( 451 | 3.0, 452 | { value:0.9}, 453 | 0.5 454 | ); 455 | dictObject.EqualizerSceneDisplayFirefoxScale = { value: 1.0}; 456 | anim("EqualizerSceneDisplayFirefoxScale",dictObject.EqualizerSceneDisplayFirefoxScale).to( 457 | 40.77, 458 | { value: 1.5 }, 459 | 2.0, 460 | Timeline.Easing.Linear.None 461 | ); 462 | 463 | anim("EqualizerSceneShowModel",dictObject.EqualizerSceneShowModel).to( 464 | 54.606, 465 | { value: 0.0 }, 466 | 1.5, 467 | Timeline.Easing.Linear.None 468 | ); 469 | 470 | 471 | dictObject.EqualizerSceneFinish = { value: 0.0}; 472 | anim("EqualizerSceneFinish",dictObject.EqualizerSceneFinish).to( 473 | 55.606, 474 | { value:1.0 }, 475 | function() { showCredits(); }, 476 | 0.00001, 477 | Timeline.Easing.Linear.None 478 | ); 479 | 480 | 481 | 482 | dictObject.ModelRotate = { value: 0.0}; 483 | anim("ModelRotate",dictObject.ModelRotate).to( 484 | 14.756, 485 | { value:1.0 }, 486 | selectAxis, 487 | 0.1, 488 | Timeline.Easing.Cubic.EaseIn 489 | ).to( 490 | 0.0, 491 | { value:0.0}, 492 | 0.00001 493 | ); 494 | 495 | 496 | return dictObject; 497 | }; -------------------------------------------------------------------------------- /js/timeline.js: -------------------------------------------------------------------------------- 1 | /** -*- compile-command: "jslint-cli timeline.js" -*- */ 2 | // Timeline.js v0.1 / 2011-05-01 3 | // A compact JavaScript animation library with a GUI timeline for fast editing. 4 | // by Marcin Ignac (http://marcinignac.com) 5 | // 6 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 7 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 8 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 9 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 10 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 11 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 12 | // IN THE SOFTWARE. 13 | 14 | var Timeline = function() { 15 | this.name = "Global"; 16 | this.anims = []; 17 | this.time = 0; 18 | this.totalTime = 0; 19 | this.loopCount = 0; 20 | this.loopMode = 0; 21 | this.playing = true; 22 | }; 23 | 24 | Timeline.currentInstance = null; 25 | 26 | Timeline.getGlobalInstance = function() { 27 | if (!Timeline.globalInstance) { 28 | Timeline.globalInstance = new Timeline(); 29 | } 30 | return Timeline.globalInstance; 31 | }; 32 | 33 | //Possible values of n: 34 | //-1 infinite loop 35 | //0 play forever without looping, continue increasing time even after last animation 36 | //1 play once and stop at the time the last animation finishes 37 | //>1 loop n-times 38 | Timeline.prototype.loop = function(n) { 39 | this.loopMode = n; 40 | }; 41 | 42 | Timeline.prototype.stop = function() { 43 | this.playing = false; 44 | this.time = 0; 45 | this.prevTime = this.time - 1/30; //FIXME 1/30 46 | }; 47 | 48 | Timeline.prototype.pause = function() { 49 | this.playing = false; 50 | }; 51 | 52 | Timeline.prototype.play = function() { 53 | this.playing = true; 54 | }; 55 | 56 | Timeline.prototype.start = function() { 57 | var self = this; 58 | setInterval(function() { 59 | self.update(1.0/30.0); 60 | }, 1000/30); 61 | }; 62 | 63 | Timeline.prototype.preUpdate = function() { 64 | //placeholder for hooks like GUI rendering 65 | }; 66 | 67 | Timeline.prototype.update = function(dt) { 68 | this.preUpdate(); 69 | 70 | if (this.playing) { 71 | this.totalTime += dt; 72 | this.prevTime = this.time; 73 | this.time += dt; 74 | } 75 | 76 | if (this.loopMode !== 0) { 77 | var animationEnd = this.findAnimationEnd(); 78 | if (this.time > animationEnd) { 79 | this.loopCount++; 80 | this.time = 0; 81 | } 82 | if (this.loopMode == -1) { 83 | //loop infinitely 84 | } 85 | else { 86 | if (this.loopCount >= this.loopMode) { 87 | this.playing = false; 88 | } 89 | } 90 | } 91 | this.applyValues(); 92 | }; 93 | 94 | Timeline.prototype.findAnimationEnd = function() { 95 | var endTime = 0; 96 | for(var i=0; i endTime) { 98 | endTime = this.anims[i].endTime; 99 | } 100 | } 101 | return endTime; 102 | }; 103 | 104 | Timeline.prototype.applyValues = function() { 105 | for(var i=0 , l = this.anims.length; i/tmp/t.json 3 | python -mjson.tool /tmp/t.json 4 | -------------------------------------------------------------------------------- /tool/gradient.sh: -------------------------------------------------------------------------------- 1 | path=$(pwd) 2 | src=$(realpath $1) 3 | cd ~/dev/DistanceMapGenerator 4 | ./distancemap $src /tmp/distance.png 5 | ./gradient /tmp/distance.png /tmp/gradient 6 | convert /tmp/gradient_dx.png /tmp/gradient_dy.png /tmp/smooth.png -combine ${src/.png/}_grad.png 7 | -------------------------------------------------------------------------------- /twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/twitter.png -------------------------------------------------------------------------------- /zik.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedricpinson/DemoJS-FFF/576b0ab080c1347d90e4dfec6056f24db671bd59/zik.ogg --------------------------------------------------------------------------------