Quelcode des Partikelsystems Boden
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

particle.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. //
  2. // particle.cpp
  3. // emptyExample
  4. //
  5. // Created by Sebastian Holzki on 16.04.19.
  6. //
  7. #include "particle.hpp"
  8. Particle::Particle()
  9. {
  10. // std::cout << "partikel konstruktor" << std::endl;
  11. }
  12. // -----------------------------------
  13. Particle::Particle(ofVec2f _position)
  14. {
  15. position = _position;
  16. // std::cout << "partikel konstruktor überladen" << std::endl;
  17. }
  18. // -----------------------------------
  19. Particle::~Particle()
  20. {
  21. }
  22. // -----------------------------------
  23. void Particle::setup(ofVec2f _position, float sceneHeight){
  24. this->position = _position;
  25. velocity.set(0,0);
  26. age = 0.0;
  27. maxLife = 25.0;
  28. color.set(ofRandom(100,150),ofRandom(100,150),ofRandom(20,255));
  29. size = 1.5;
  30. mass = 100;
  31. activeSlowingDown = 0;
  32. factorOfSlowingDown = 0.3;
  33. activeSpeedingUp = factorOfSlowingDown;
  34. factorOfSpeedingUp = 1;
  35. scaleFactorPerDeltaT = 0.002;
  36. distanceToCenter = 0;
  37. angleToCenter = 0;
  38. aging = true;
  39. particleIsOnGround = isTheSetupPositionOnTheGround(position, sceneHeight);
  40. }
  41. // -----------------------------------
  42. void Particle::update(float deltaT, particleMode currentMode, vector<ObjectPhysics*>* objectPhysics, vector<CheckedInVisitor*>* checkedInVisitors, float _sceneWidth, float _sceneHeight){
  43. sceneWidth = _sceneWidth;
  44. sceneHeight = _sceneHeight;
  45. //angle and distance calculation to be able to map later
  46. updateAngleToCenter(sceneHeight/2, sceneHeight/2); //updates the angle of the particle in relation to the center of the logical scene
  47. updateDistanceToCenter(sceneHeight/2, sceneHeight/2, sceneHeight); //needs the center of the LED-Floor as reference
  48. switch ( currentMode ) {
  49. case PARTICLE_MODE_DEFAULT: {
  50. //what does the PARTICLE do if the mode is 'PARTICLE_MODE_DEFAULT'
  51. if(currentMode != lastMode && lastMode == PARTICLE_MODE_POLYMESH){
  52. activeSpeedingUp = factorOfSlowingDown;
  53. }
  54. if(activeSpeedingUp < factorOfSpeedingUp){
  55. //This is helping to make the transition from faster to slower a little smoother
  56. //The particle will be slowed down in every iteration until the "destination"-speed is reached
  57. activeSpeedingUp = activeSpeedingUp + deltaT;
  58. }
  59. attractParticle(objectPhysics, checkedInVisitors);
  60. position += activeSpeedingUp * (velocity * deltaT) ;
  61. aging = true;
  62. if(aging == true){
  63. age += deltaT;
  64. }
  65. break;
  66. }
  67. //------------------------
  68. case PARTICLE_MODE_POLYMESH: {
  69. //what does the PARTICLE do if its mode is 'PARTICLE_MODE_POLYMESH'
  70. if(currentMode != lastMode){
  71. activeSlowingDown = 1;
  72. }
  73. if(activeSlowingDown > factorOfSlowingDown){
  74. //This is helping to make the transition from faster to slower a little smoother
  75. //The particle will be slowed down in every iteration until the "destination"-speed is reached
  76. activeSlowingDown = activeSlowingDown - deltaT;
  77. }
  78. position += activeSlowingDown * (velocity * deltaT) ;
  79. aging = true;
  80. if(aging == true){
  81. age += deltaT;
  82. }
  83. break;
  84. }
  85. //------------------------
  86. case PARTICLE_MODE_TORNADO: {
  87. //what does the PARTICLE do if the mode is 'PARTICLE_MODE_TORNADO'
  88. break;
  89. }
  90. //------------------------
  91. case PARTICLE_MODE_RFID: {
  92. //what does the PARTICLE do if its mode is 'PARTICLE_MODE_RFID'
  93. if(currentMode != lastMode && lastMode == PARTICLE_MODE_POLYMESH){
  94. activeSpeedingUp = factorOfSlowingDown;
  95. }
  96. if(activeSpeedingUp < factorOfSpeedingUp){
  97. //This is helping to make the transition from faster to slower a little smoother
  98. //The particle will be slowed down in every iteration until the "destination"-speed is reached
  99. activeSpeedingUp = activeSpeedingUp + deltaT;
  100. }
  101. position += activeSpeedingUp * (velocity * deltaT) ;
  102. size += scaleFactorPerDeltaT * deltaT ;
  103. aging = true;
  104. if(aging == true){
  105. age += deltaT;
  106. }
  107. break;
  108. }
  109. //------------------------
  110. default: {}
  111. } //end of switch
  112. // *** PARTICLE MOVEMENT CONTROL AREA *** PARTICLE MOVEMENT CONTROL AREA ***
  113. //first we slow down the particle in their y-direction,
  114. if(particleIsOnGround == false){
  115. if(velocity.y < 0 && velocity.y > -0.4){
  116. velocity.y *= 0.995;
  117. }
  118. }
  119. if(distanceToCenter > sceneHeight/4*3){
  120. }
  121. if(particleIsOnGround == false){
  122. if(position.x < (sceneHeight)){
  123. position.x = sceneWidth;
  124. }
  125. else if(position.x >= sceneWidth){
  126. position.x = sceneHeight;
  127. }
  128. }
  129. size += scaleFactorPerDeltaT * age ;
  130. lastMode = currentMode;
  131. }
  132. // -----------------------------------
  133. void Particle::draw(typeOfView activeTypeOfView){
  134. updateColor();
  135. ofSetColor(color);
  136. ofSetCircleResolution(10);
  137. mapParticle(sceneWidth, sceneHeight);
  138. ofDrawCircle(position, size);
  139. if(activeTypeOfView == MAPPED){
  140. ofDrawBitmapString(distanceToCenter, position);
  141. }
  142. ofSetCircleResolution(35);
  143. }
  144. //-----------------------------------
  145. float Particle::getMaxLife(){
  146. return maxLife;
  147. }
  148. //-----------------------------------
  149. float Particle::getAngle(){
  150. return angleToCenter;
  151. }
  152. //-----------------------------------
  153. ofVec2f Particle::getPosition(){
  154. return position;
  155. }
  156. //-----------------------------------
  157. void Particle::setRandomVelocity(){
  158. velocity.set(ofRandom(-50,50), ofRandom(-50,50));
  159. }
  160. //-----------------------------------
  161. void Particle::setRandomVelocityOnlyGoingUp(){
  162. velocity.set(ofRandom(-50,50), ofRandom(-50,-1));
  163. }
  164. //-----------------------------------
  165. void Particle::updateColor(){
  166. if(getAgeNorm() >= 1){
  167. color.set(69 + getAgeNorm() * 104, 164 - getAgeNorm() * 95 , 220, (color , 0));
  168. }
  169. else{
  170. color.set(69 + getAgeNorm() * 104, 164 - getAgeNorm() * 95 , 220, (color, (1 - getAgeNorm()) * 255 ));
  171. }
  172. }
  173. //-----------------------------------
  174. void Particle::attractParticle(vector<ObjectPhysics*>* objectPhysics, vector<CheckedInVisitor*>* checkedInVisitors){
  175. if(particleIsOnGround == true){
  176. for(int i = 0; i < objectPhysics->size(); i++){
  177. if(( (*objectPhysics).at(i)->type == "attraktor" ) && (objectPhysics->at(i)->attracting == true)){
  178. ofVec2f force;
  179. force.set(objectPhysics->at(i)->getPosition() - position);
  180. if(force.length() < 150){
  181. velocity += force.getNormalized() * 40;
  182. }
  183. if(force.length() < 50){
  184. velocity -= force.getNormalized() * 20;
  185. }
  186. }
  187. }
  188. }
  189. if(particleIsOnGround == false){
  190. for(int i = 0; i < checkedInVisitors->size(); i++){
  191. float ageOfCheckedInVisitor = checkedInVisitors->at(i)->getAge();
  192. if(( ageOfCheckedInVisitor < 30.0 )){
  193. ofVec2f force;
  194. force.set(checkedInVisitors->at(i)->getBottom() - position);
  195. float forceLength = force.length();
  196. if(forceLength < 250){
  197. force = force.getNormalized()* 30 * 4/checkedInVisitors->at(i)->getAge();
  198. velocity += force;
  199. }
  200. }
  201. }
  202. }
  203. }
  204. //-----------------------------------
  205. float Particle::getAgeNorm(){
  206. return age/maxLife;
  207. }
  208. //-----------------------------------
  209. void Particle::updateAngleToCenter(float centerX, float centerY){
  210. //case 1 ( distance =< radius )
  211. ofVec2f center(centerX, centerY);
  212. ofVec2f particleToCenter = position - center;
  213. //Subtraction: (position of particle) - (position of floor center) = vector between center and particle
  214. ofVec2f referenceVector(0, 0.5);
  215. angleToCenter = particleToCenter.getNormalized().angle(referenceVector.getNormalized());
  216. angleToCenter = angleToCenter + 180;
  217. //case 2 ( distance > radius
  218. }
  219. //-----------------------------------
  220. void Particle::updateDistanceToCenter(float centerX, float centerY, float sceneHeight){
  221. distanceToCenterLastFrame = distanceToCenter;
  222. if(particleIsOnGround == true){
  223. ofVec2f centerOfFloor(centerX, centerY);
  224. distanceToCenter = position.distance(centerOfFloor);
  225. }
  226. if(particleIsOnGround == false){
  227. distanceToCenter = sceneHeight/2 + sceneHeight - position.y;
  228. }
  229. if(distanceToCenterLastFrame >= sceneHeight/2 && distanceToCenter < sceneHeight/2){
  230. //was passiert wenn es vorher größer als radius war, dann kleiner
  231. particleJumpedOnGround = true;
  232. }
  233. if(distanceToCenterLastFrame <= sceneHeight/2 && distanceToCenter > sceneHeight/2){
  234. //was passiert wenn es vorher kleiner als radius war, dann größer
  235. particleJumpedOffGround = true;
  236. }
  237. }
  238. //-----------------------------------
  239. bool Particle::isTheSetupPositionOnTheGround(ofVec2f _position, float sceneHeight){
  240. ofVec2f centerOfFloor(sceneHeight/2, sceneHeight/2);
  241. distanceToCenter = _position.distance(centerOfFloor);
  242. if(distanceToCenter > (sceneHeight/2)){
  243. return false;
  244. }else{
  245. return true;
  246. }
  247. }
  248. //-----------------------------------
  249. void Particle::mapParticle(float sceneWidth, float sceneHeight){
  250. //The mapping works with the information about the particle's distance to the center and its angle to the center (distanceToCenter, angleToCenter).
  251. //if the particle gets too far away from the center, it will leave the LED-Floor. Then there is a small black gap.
  252. //After that it will hit the "Stelen". The Stelen are represented by a 360degree circle, 40deg for every Stele, 20deg for every black gap in between.
  253. if(particleJumpedOffGround == true){
  254. position.y = sceneHeight - 20;
  255. //sceneWidth noch ändern damit es sich am kreisumfang orientiert
  256. position.x = (sceneHeight + angleToCenter/360 * (sceneWidth - sceneHeight));
  257. position.x += (sceneWidth - sceneHeight)/12 ; //so we dont have 0 deg exactly at the first pixel of the stelen
  258. if(position.x > sceneWidth){
  259. float difference = position.x - sceneWidth;
  260. position.x = sceneHeight + difference;
  261. }
  262. ofVec2f referenceVector(0.0, 1.0); //will be used to get an angle of the velocityvector
  263. referenceVector.getNormalized();
  264. float lotAmKreisZuAustrittspunkt;
  265. if(angleToCenter < 90){
  266. lotAmKreisZuAustrittspunkt = 270 - angleToCenter;
  267. }
  268. if(angleToCenter >= 90){
  269. lotAmKreisZuAustrittspunkt = angleToCenter - 90;
  270. }
  271. float velocityAngleZuReference = velocity.angle(referenceVector);
  272. // velocity = velocity.rotate(270 - lotAmKreisZuAustrittspunkt);
  273. float k = velocity.length();
  274. velocity.set(0, -k);
  275. particleJumpedOffGround = false;
  276. // cout << "particleJumpedOffGround" << endl;
  277. }
  278. if(particleJumpedOnGround == true){
  279. //Vorerst nicht implementiert
  280. // particleJumpedOnGround = false;
  281. }
  282. if(distanceToCenter > sceneHeight/2){
  283. particleIsOnGround = false;
  284. }else if(distanceToCenter <= sceneHeight/2){
  285. particleIsOnGround = true;
  286. }
  287. //setze bei übertritt einmal y auf sceneHeight
  288. //setze x genau auf angle/360 * sceneWidth
  289. //setze velocity neu mit weg über gedrehtes lot (siehe blatt)
  290. //führe berechnung normal weiter aus
  291. //correcting the velocity to the new way it is going to be displayed
  292. }