WOWCube Docs logo
WOWCube Docs
Mission Control
Section Shortcuts
APIExamplesSourceWOWConnectChangelog
Filters
SDK and language defaults persist in cookies.
SDK version
Navigation Tree
Collapsed by default, focused on the active path.
Made byMcKay Seamons
GitHub
  1. Home
  2. Docs
  3. Examples
  4. Circles.cpp
Mission NodeSDK 6.3C++renderingProject Included

Circles.cpp

Example: Circles.cpp

Examples / SDK 6.3 / C++ / rendering / Simple Shapes - Circles / project / src
Circles.cpp
CPP
1// This file is generated by WOWCube SDK project wizard
2
3#include <stdint.h>
4#include <string>
5#include <vector>
6#include <string>
7#include <memory>
8
9#include "AppManager.h"
10#include "Math/Vec2.h"
11
12#include "Circles.h"
13
14using namespace Cubios::Gfx;
15
16//Applicaton initialization callback. Called once when CUB application starts
17void OnInit(Cubios::AppManager& appMgr)
18{
19 Circles* theApp = new Circles();
20
21 appMgr.SetApplication(theApp,"AAbbCCddEE");
22
23 theApp->InitializeResources();
24
25}
26
27
28Circles::Circles():numMagnets(0),magnetsShift(0),numParticles(0)
29{
30}
31
32Circles::~Circles()
33{
34}
35
36void Circles::InitializeResources()
37{
38 LOG_i("\n");
39 LOG_i("WOWCube SDK Example \"Simple Shapes - Circles\" ***\n");
40
41 LOG_i("Cubeapp is initializing...");
42 LOG_i("Cubeapp is started on module %d",this->Module);
43
44 //create 4 attractors
45 createMagnet(40,40);
46 createMagnet(50,180);
47 createMagnet(150,80);
48 createMagnet(120,120);
49
50 LOG_i("Done.");
51}
52
53
54//This callback is called every "tick" of cubeapp application loop
55void Circles::on_Tick(uint32_t currentTime, uint32_t deltaTime)
56{
57}
58
59//This callback is called every time device is about to render visuals. Use it for calling your rendering code.
60void Circles::on_Render(std::array<Cubios::Screen, 3>& screens)
61{
62 for(auto it = screens.begin(); it != screens.end(); ++it)
63 {
64 Cubios::GFX_setRenderTarget(it->ID());
65
66 Cubios::GFX_clear(MyColors::marsh);
67
68 //Render particles
69 renderParticles();
70
71 Cubios::GFX_render();
72 }
73}
74
75//The "physics" callback. Gets called recurrently with at least 33ms resolution or less depending on the load.
76void Circles::on_PhysicsTick(const std::array<Cubios::Screen, 3>& screens)
77{
78 //Slowly change positions of attractors
79 moveMagnets();
80}
81
82//This callback is called on programmable timer (if any)
83void Circles::on_Timer(uint8_t timerID)
84{
85}
86
87//The cube topology change callback. Gets called when cube is twisted and its topological desctiption has been changed
88void Circles::on_Twist(const Cubios::TOPOLOGY_twistInfo_t& twist)
89{
90}
91
92//The "inner network" callback. Gets called when WOWCube module receives a data packet from other module
93void Circles::on_Message(uint32_t type, uint8_t* pkt, u32_t size)
94{
95}
96
97//The external data transfer callback. Gets called when WOWCube module receives a data over BLE from an external source
98void Circles::on_ExternalMessage(uint8_t* pkt, u32_t size)
99{
100}
101
102//Screen pat callback
103void Circles::on_Pat(uint32_t count)
104{
105}
106
107float Circles::distanceSquared(float x1, float y1, float x2, float y2)
108{
109 return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
110}
111
112void Circles::createMagnet(float x,float y)
113{
114 if(this->numMagnets<NUM_MAGNETS)
115 {
116 this->magnets[numMagnets].x = x;
117 this->magnets[numMagnets].y = y;
118 this->magnets[numMagnets].orbit = 100.0;
119 this->magnets[numMagnets].size = 1.0;
120
121 this->createParticles(x,y,numMagnets);
122
123 this->numMagnets++;
124 }
125}
126
127void Circles::moveMagnets()
128{
129 float fSin = sin(this->magnetsShift);
130
131 for(int i=0;i<numMagnets;i++)
132 {
133 magnets[i].x+=sin(this->magnetsShift*(i+1))/2;
134 }
135 this->magnetsShift++;
136 if(this->magnetsShift>360) this->magnetsShift=0;
137}
138
139void Circles::createParticles(float x, float y,int magnet)
140{
141 for(int i=0;i<PARTICLES_PER_MAGNET;i++)
142 {
143 float r1 = (float)(Cubios::random(0,100))/100.0;
144 float r2 = (float)(Cubios::random(0,100))/100.0;
145
146 this->particles[numParticles].x = x;
147 this->particles[numParticles].y = y;
148 this->particles[numParticles].shx = x;
149 this->particles[numParticles].shy = y;
150
151 this->particles[numParticles].angle = 0;
152 this->particles[numParticles].size = 0+r1*6.5;
153 this->particles[numParticles].speed = (0.001 + ((particles[numParticles].size+1)/40.0)*0.045);
154 this->particles[numParticles].force = 0.98 - r2*0.15;
155 this->particles[numParticles].orbit = 1.0;
156
157 this->particles[numParticles].magnet = magnet;
158
159 this->numParticles++;
160 }
161}
162
163void Circles::renderParticles()
164{
165
166 for(int i=0;i<numParticles;i++)
167 {
168 float currentDistance = -1;
169 float closestDistance = -1;
170 int closestMagnet = -1;
171
172 // Attraction force vector
173 Cubios::Math::Vec2 force;
174 force.X = 0;
175 force.Y = 0;
176
177 // Figure out the most influential attractor for a particle and calculate attraction force
178 for(int j=0;j<numMagnets;j++)
179 {
180 currentDistance = this->distanceSquared(particles[i].x,particles[i].y,magnets[j].x,magnets[j].y) - magnets[j].orbit*magnets[j].orbit;
181
182 if(particles[i].magnet!=j)
183 {
184 float fx = magnets[j].x - particles[i].x;
185
186 if( fx > -MAGNETIC_FORCE_THRESHOLD && fx < MAGNETIC_FORCE_THRESHOLD )
187 {
188 force.X += fx / MAGNETIC_FORCE_THRESHOLD;
189 }
190
191 float fy = magnets[j].y - particles[i].y;
192 if( fy > -MAGNETIC_FORCE_THRESHOLD && fy < MAGNETIC_FORCE_THRESHOLD )
193 {
194 force.Y += fy / MAGNETIC_FORCE_THRESHOLD;
195 }
196
197 }
198
199 if( closestMagnet == -1 || currentDistance < closestDistance )
200 {
201 closestDistance = currentDistance;
202 closestMagnet = j;
203 }
204
205 }
206
207 if( particles[i].magnet == -1 || particles[i].magnet != closestMagnet )
208 {
209 particles[i].magnet = closestMagnet;
210 }
211
212 // Spin the particle
213 particles[i].angle += particles[i].speed*0.5;
214
215 // Translate the particle towards the magnet position
216 particles[i].shx += ( (magnets[closestMagnet].x+(force.X*4)) - particles[i].shx) * particles[i].speed*0.5;
217 particles[i].shy += ( (magnets[closestMagnet].y+(force.Y*4)) - particles[i].shy) * particles[i].speed*0.5;
218
219 float fSin = sin(i+particles[i].angle);
220 float fCos = cos(i+particles[i].angle);
221
222 // Apply integral change to the particle's position
223 particles[i].x = particles[i].shx + fSin * (particles[i].orbit*particles[i].force);
224 particles[i].y = particles[i].shy + fCos * (particles[i].orbit*particles[i].force);
225
226 // Slowly inherit the closest magnets orbit
227 particles[i].orbit += ( magnets[closestMagnet].orbit - particles[i].orbit )* 0.1;
228
229 // Change particle color
230 int color = (int)(255.0/(particles[i].size+1))*20;
231
232 // Draw particle
233 Cubios::GFX_drawSolidCircle((int)particles[i].x,(int)particles[i].y, (int)(particles[i].size)*3, (int)(color)|((int)(color*0.8)<<8)|((int)(color*0.9)<<16)|(255<<24));
234 }
235
236}
237
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.
Context Rail

Project files

Circles.cpp
project/src/Circles.cpp
Circles.h
project/src/Circles.h
wowcubeapp-build.json
project/wowcubeapp-build.json
Context Rail

Related nodes

Circles.h
Examples / SDK 6.3 / C++ / rendering / Simple Shapes - Circles / project / src
Simple Shapes - Circles
Examples / SDK 6.3 / C++ / rendering
info.json
Examples / SDK 6.3 / C++ / rendering / Simple Shapes - Circles
wowcubeapp-build.json
Examples / SDK 6.3 / C++ / rendering / Simple Shapes - Circles / project
Previous Node
info.json
Examples / SDK 6.3 / C++ / rendering / Simple Shapes - Circles
Next Node
Circles.h
Examples / SDK 6.3 / C++ / rendering / Simple Shapes - Circles / project / src