Example: Circles.cpp
1// This file is generated by WOWCube SDK project wizard23#include <stdint.h>4#include <string>5#include <vector>6#include <string>7#include <memory>89#include "AppManager.h"10#include "Math/Vec2.h"1112#include "Circles.h"1314using namespace Cubios::Gfx;1516//Applicaton initialization callback. Called once when CUB application starts17void OnInit(Cubios::AppManager& appMgr)18{19 Circles* theApp = new Circles();2021 appMgr.SetApplication(theApp,"AAbbCCddEE");2223 theApp->InitializeResources();2425}262728Circles::Circles():numMagnets(0),magnetsShift(0),numParticles(0)29{30}3132Circles::~Circles()33{34}3536void Circles::InitializeResources()37{38 LOG_i("\n");39 LOG_i("WOWCube SDK Example \"Simple Shapes - Circles\" ***\n");4041 LOG_i("Cubeapp is initializing...");42 LOG_i("Cubeapp is started on module %d",this->Module);4344 //create 4 attractors45 createMagnet(40,40);46 createMagnet(50,180);47 createMagnet(150,80);48 createMagnet(120,120);4950 LOG_i("Done.");51}525354//This callback is called every "tick" of cubeapp application loop55void Circles::on_Tick(uint32_t currentTime, uint32_t deltaTime)56{57}5859//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());6566 Cubios::GFX_clear(MyColors::marsh);6768 //Render particles69 renderParticles();7071 Cubios::GFX_render();72 }73}7475//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 attractors79 moveMagnets();80}8182//This callback is called on programmable timer (if any)83void Circles::on_Timer(uint8_t timerID)84{85}8687//The cube topology change callback. Gets called when cube is twisted and its topological desctiption has been changed88void Circles::on_Twist(const Cubios::TOPOLOGY_twistInfo_t& twist)89{90}9192//The "inner network" callback. Gets called when WOWCube module receives a data packet from other module93void Circles::on_Message(uint32_t type, uint8_t* pkt, u32_t size)94{95}9697//The external data transfer callback. Gets called when WOWCube module receives a data over BLE from an external source98void Circles::on_ExternalMessage(uint8_t* pkt, u32_t size)99{100}101102//Screen pat callback103void Circles::on_Pat(uint32_t count)104{105}106107float Circles::distanceSquared(float x1, float y1, float x2, float y2)108{109 return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);110}111112void 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;120121 this->createParticles(x,y,numMagnets);122123 this->numMagnets++;124 }125}126127void Circles::moveMagnets()128{129 float fSin = sin(this->magnetsShift);130131 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}138139void 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;145146 this->particles[numParticles].x = x;147 this->particles[numParticles].y = y;148 this->particles[numParticles].shx = x;149 this->particles[numParticles].shy = y;150151 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;156157 this->particles[numParticles].magnet = magnet;158159 this->numParticles++;160 }161}162163void Circles::renderParticles()164{165166 for(int i=0;i<numParticles;i++)167 {168 float currentDistance = -1;169 float closestDistance = -1;170 int closestMagnet = -1;171172 // Attraction force vector173 Cubios::Math::Vec2 force;174 force.X = 0;175 force.Y = 0;176177 // Figure out the most influential attractor for a particle and calculate attraction force178 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;181182 if(particles[i].magnet!=j)183 {184 float fx = magnets[j].x - particles[i].x;185186 if( fx > -MAGNETIC_FORCE_THRESHOLD && fx < MAGNETIC_FORCE_THRESHOLD )187 {188 force.X += fx / MAGNETIC_FORCE_THRESHOLD;189 }190191 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 }196197 }198199 if( closestMagnet == -1 || currentDistance < closestDistance )200 {201 closestDistance = currentDistance;202 closestMagnet = j;203 }204205 }206207 if( particles[i].magnet == -1 || particles[i].magnet != closestMagnet )208 {209 particles[i].magnet = closestMagnet;210 }211212 // Spin the particle213 particles[i].angle += particles[i].speed*0.5;214215 // Translate the particle towards the magnet position216 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;218219 float fSin = sin(i+particles[i].angle);220 float fCos = cos(i+particles[i].angle);221222 // Apply integral change to the particle's position223 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);225226 // Slowly inherit the closest magnets orbit227 particles[i].orbit += ( magnets[closestMagnet].orbit - particles[i].orbit )* 0.1;228229 // Change particle color230 int color = (int)(255.0/(particles[i].size+1))*20;231232 // Draw particle233 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 }235236}237