void updateParticle(ParticleManager& sourceManager, int sourceId, ParticleManager& destinationManager, int destinationId) { destinationManager.getParticleMass(destinationId) = sourceManager.getParticleMass(sourceId); destinationManager.getParticlePosition(destinationId) = sourceManager.getParticlePosition(sourceId); destinationManager.getParticleVelocity(destinationId) = sourceManager.getParticleVelocity(sourceId); destinationManager.getParticleForce(destinationId) = sourceManager.getParticleForce(sourceId); destinationManager.getParticleColor(destinationId) = sourceManager.getParticleColor(sourceId); }
// Add attractive force void addAttractiveForce(ParticleManager& foodManager, ParticleManager& snakeManager) { int attractiveCoeff = 50; glm::vec2 attractiveForce = foodManager.getParticlePosition(0) - snakeManager.getParticlePosition(0); float d = glm::length(attractiveForce); attractiveForce = glm::normalize(attractiveForce); // Plus on divise et plus c'est petit : pluattractivecoeff augmente et mois l'attraction est forte au loin snakeManager.addForceToParticle(0, glm::vec2(attractiveForce[0]/(attractiveCoeff*d), attractiveForce[1]/(attractiveCoeff*d))); }
// Copy a particle int copyParticle(ParticleManager& sourceManager, ParticleManager& destinationManager, int id) { int newId = destinationManager.addParticle(sourceManager.getParticleMass(id), sourceManager.getParticlePosition(id), sourceManager.getParticleVelocity(id), sourceManager.getParticleForce(id), sourceManager.getParticleColor(id)); return newId; }
// Add repulsive force void addRepulsiveForce(ParticleManager& repulsiveManager, ParticleManager& snakeManager) { if(repulsiveManager.getCount() > 0) { for(int i = 0; i < snakeManager.getCount(); ++i) { for(int j = 0; j < repulsiveManager.getCount(); ++j) { glm::vec2 repulse = snakeManager.getParticlePosition(i) - repulsiveManager.getParticlePosition(j); float d = glm::length(repulse); repulse = glm::normalize(repulse); int repulsiveCoeff = 40; if(d < 0.2) { // Plus on divise et plus c'est petit : pluattractivecoeff augmente et mois l'attraction est forte au loin snakeManager.addForceToParticle(i, glm::vec2(repulse[0]/(repulsiveCoeff*d), repulse[1]/(repulsiveCoeff*d))); } } } } }
// Add a particle to the Snake void addParticletoSnake(ParticleGraph& graph, int id, ParticleManager& foodManager, ParticleManager& snakeManager) { id = snakeManager.addParticleToHead(foodManager.getParticleMass(id), foodManager.getParticlePosition(id), foodManager.getParticleVelocity(id), foodManager.getParticleForce(id), snakeManager.getHeadColor()); foodManager.clear(); std::pair<unsigned int, unsigned int> pair (id, snakeManager.getCount() - 2); graph.push_back(pair); snakeManager.getParticleColor(1) = snakeManager.getParticleColor(2); }
// Check collision between snake and food int checkFoodCollision(ParticleGraph& snakeGraph, ParticleManager& snakeManager, ParticleManager& foodManager, ParticleManager& fireworkManager, float step, int init) { for(int i = init; i < foodManager.getCount(); ++i) { if(foodManager.getParticleX(i) - step * foodManager.getParticleMass(i) <= snakeManager.getParticleX(0) && snakeManager.getParticleX(0) <= foodManager.getParticleX(i) + step * foodManager.getParticleMass(i) && foodManager.getParticleY(i) - step * foodManager.getParticleMass(i) <= snakeManager.getParticleY(0) && snakeManager.getParticleY(0) <= foodManager.getParticleY(i) + step* foodManager.getParticleMass(i)) { fireworkManager.addCircleParticlesAtPosition(3, snakeManager.getParticlePosition(0), snakeManager.getParticleColor(1), 25); addParticletoSnake(snakeGraph, i, foodManager, snakeManager); foodManager.addRandomParticle(snakeManager.getCount()); return i; } } return -1; }
void UniversalForce::apply(ParticleManager &pm) { unsigned int count = pm.getSize(); std::vector<unsigned int> toErase; bool mustErase = false; for(int i = 0; i < count; ++i){ // ------------------------------------- // ----- calcul de la durée de vie ----- // ------------------------------------- if(pm.decreaseParticleLifetime(i) == true){ toErase.push_back(i); mustErase = true; } // --------------------- // ----- Répulsion ----- // --------------------- glm::vec2 p1=pm.getParticlePosition(i); for(int j = 0; j < count; ++j){ if(i != j){ glm::vec2 p2=pm.getParticlePosition(j); glm::vec2 vect = p2 - p1; float norm = glm::length(vect); glm::vec2 force = glm::vec2(0.0); // Répulsion if(norm < m_fLInf - 0.04f){ force = m_fKRep*(1-(m_fLInf-0.04f)/glm::max(norm,0.0001f))*(vect); } // Sticky if(norm > m_fLInf && norm < m_fLSup){ force = m_fKSticky*(1-m_fLInf/glm::max(norm,0.0001f))*(vect); } pm.addForce(i, force); } } // Fin répulsion // ---------------------------------------- // - Attraction vers le centre de l'écran - // ---------------------------------------- glm::vec2 pos = pm.getParticlePosition(i); glm::vec2 p2 = glm::vec2(0.,0.); glm::vec2 vect = p2 - pos; float norm = glm::length(vect); glm::vec2 force = glm::vec2(0.0); force = m_fConstK*(1-m_fConstL/glm::max(norm,0.0001f))*(vect); pm.addForce(i, force); // Fin attraction centre // ----------------- // ----- Brake ----- // ----------------- glm::vec2 v1=pm.getParticleVelocity(i); for(int j = 0; j < count; ++j){ if(i != j){ glm::vec2 v2 = pm.getParticleVelocity(j); glm::vec2 p1 = pm.getParticlePosition(i); glm::vec2 p2 = pm.getParticlePosition(j); if(m_fDt > 0){ glm::vec2 force = glm::vec2(0.0, 0.0); float norm = glm::length(p2-p1); if(norm < m_fBrakeL){ force = m_fBrakeV*((v2-v1)/m_fDt); } // amortissement if(m_fBrakeAmort > 0.0f){ glm::vec2 amortissment = glm::vec2(0.0); Leapfrog::ParticleState actualState; actualState.position = pm.getParticlePosition(i); actualState.velocity = pm.getParticleVelocity(i); Leapfrog::ParticleState nextState = Leapfrog::getNextState(i, pm, m_fDt); if(m_fDt > 0.0){ glm::vec2 dV = (nextState.velocity - actualState.velocity) / m_fDt; dV *= m_fBrakeAmort; pm.addForce(i, -dV); } } pm.addForce(i, force); } } } // fin Brake } // effacer les particules en fin de vie if(mustErase){ for(unsigned int i = 0; i < toErase.size(); ++i){ pm.killParticle(i); } } }