int SpringSystem::CreateSpring(int particleId1, int particleId2) { Spring* spr = GetSpring(particleId1, particleId2); if (spr) { std::cout << "CreateSpring: found duplicate spring.\n"; return spr->GetId(); } int n = m_springs.size(); spr = new Spring(n, GetParticle(particleId1), GetParticle(particleId2)); m_springs.push_back(spr); // Add this spring to the map of springs connected to each particle m_springMap[particleId1].insert(spr); m_springMap[particleId2].insert(spr); // We have just set the natural length of the spring. // Set the min and max lengths based on this. // TODO This is a property of the squishy thing float natLen = spr->GetNaturalLength(); // TODO TEMP TEST spr->SetMaxLength(natLen * 1.5f); spr->SetMinLength(natLen * 0.7f); return n; }
// 布の形状の更新 void updateCloth(void) { // ★次の手順で質点の位置を決定する // 1. 質点に働く力を求める // 2. 質点の加速度を求める // 3. 質点の速度を更新する // 4. 質点の位置を更新する //1-1. 質点に働く力をリセット for(int y = 0; y < POINT_NUM; y++) { for(int x = 0; x < POINT_NUM; x++) { cloth->points[x][y].f.set(0, 0, 0); } } //1-2. バネの両端の質点に力を働かせる // 全てのバネについての処理 for(int i = 0; i < cloth->springs.size(); i++) { // clothオブジェクトの i 番目のバネを取得 Spring *spring = cloth->springs[i]; // i 番目のバネの自然長(spring->restLength)と、 // 現在の長さ(計算で求める)の差分を求める double d = spring->restLength - spring->length(); // 上記の値に、バネ定数 Ks を掛けた値がバネが質点に加える力 // ただし、力には向きがあるので、大きさだけではなく、方向の情報も必要 Vector3d Fs = (spring->p0->p - spring->p1->p).normalize() * d * Ks; // 両端の質点に対して、力ベクトルを加算する // バネの一方の質点に働く力(spring->p0->f)に加算(向きに注意) // バネのもう一方の質点に加わる力(spring->p1->f)に加算(向きに注意) spring->p0->f += Fs; spring->p1->f -= Fs; } //1-3. 重力、空気抵抗による力を加算する // 全ての質点に対する処理 for(int y = 0; y < POINT_NUM; y++) { for(int x = 0; x < POINT_NUM; x++) { // cloth->points[x][y].f に、重力、空気抵抗による力を加算する Point *p = &(cloth->points[x][y]); p->f += gravity * Mass - p->v * Dk; } } // 全ての質点に対する処理 for(int y = 0; y < POINT_NUM; y++) { for(int x = 0; x < POINT_NUM; x++) { Point *p = &(cloth->points[x][y]); // 2. 質点の加速度ベクトルを計算 (力ベクトル cloth->points[x][y].f を質量で割った値) // 3. 質点の速度ベクトル(cloth->points[x][y].v) を更新 p->v += p->f * (dT/Mass); // 4. 質点の位置ベクトル (cloth->points[x][y].p) を更新 if (!p->bFixed) { p->p += p->v * dT; } // オプション. 球体の内部に入るようなら、強制的に外に移動させる } } }
cpFloat Spring::springForceFunc(cpConstraint *constraint, cpFloat dist){ Spring* spring = (Spring*)cpConstraintGetUserData(constraint); if(spring->forceFunction){ return spring->forceFunction(spring, dist); } return 0; }
void SpringStroke::addPoint(float x, float y) { line->addPoint(x, y); vector<Particle*> particles = line->getPoints(); int newIndex = particles.size()-1; Particle* newPar = particles[newIndex]; if (newIndex > 0) { Spring *s = new Spring(); Particle *prevPar = particles[newIndex-1]; s->setup(prevPar, newPar); springs.push_back(s); // lock particle if close to previous one if ((*prevPar - *newPar).length() < lockDistance) { newPar->stickiness = 100; // newPar->locked = true; } } else { newPar->stickiness = 100; // newPar->locked = true; } }
void DrawNetwork() { // draw vertices glBegin(GL_POINTS); for ( int i = 0; i < physics->numberOfParticles(); ++i ) { Particle* v = physics->getParticle( i ); if(i == selected_index) glColor3f(0,1,0); else glColor3f(0.63f, 0.63f, 0.63f); glVertex2f(v->position.x, v->position.y); } glEnd(); // draw springs glBegin(GL_LINES); glColor3f(0.5,0.5,0.5); for ( int i = 0; i < physics->numberOfSprings(); ++i ) { Spring* e = physics->getSpring( i ); Particle* a = e->getOneEnd(); Particle* b = e->getTheOtherEnd(); glVertex2f(a->position.x, a->position.y); glVertex2f(b->position.x, b->position.y); } glEnd(); }
void ParticleSystem::applyForces() { if ( gravity.length() > 0.0f ) { for ( int i = 0; i < mParticles.size(); ++i ) { Particle* p = mParticles[i]; p->mAcc += gravity; } } for ( int i = 0; i < mParticles.size(); ++i ) { Particle* p = mParticles[i]; p->mAcc -= p->mVel * drag; } for ( int i = 0; i < mSprings.size(); i++ ) { Spring* f = mSprings[i]; f->apply(); } for ( int i = 0; i < attractions.size(); i++ ) { Attraction* f = attractions[i]; f->apply(); } for ( int i = 0; i < customForces.size(); i++ ) { Force* f = customForces[i]; f->apply(); } }
void Ribbon::connectSpring(){ // Connect for(int i = 0; i < myParticles.size() - 1; i++){ ofPoint dist = myParticles[i].pos - myParticles[i + 1].pos; float len = dist.length(); Spring newSpring; newSpring.set( &myParticles[i], &myParticles[i + 1], 0.05, len); springList.push_back( newSpring ); } }
//-------------------------------------------------------------- void testApp::setup(){ ofSetVerticalSync(true); ofBackground(0); for(int i=0;i<4; i++){ SpringJoint sj; sj.pos = ofVec2f(ofGetWidth()/2,10+i*195); jointList.push_back(sj); } for(int i=0;i<jointList.size()-1; i++){ Spring s; s.set(&jointList[i], &jointList[i+1], 0.05, 200); springList.push_back(s); } Spring s; s.set(&jointList[jointList.size()-1], &jointList[0], 0.05, 200); springList.push_back(s); }
Spring* SpringSystem::GetSpring(int particleId1, int particleId2) { for (auto it = m_springs.begin(); it != m_springs.end(); ++it) { Spring* spr = *it; Assert(spr); Particle* p1 = spr->GetParticle(0); Particle* p2 = spr->GetParticle(1); Assert(p1); Assert(p2); int id1 = p1->GetId(); int id2 = p2->GetId(); if ((id1 == particleId1 && id2 == particleId2) || (id2 == particleId1 && id1 == particleId2)) { return spr; } } return nullptr; }
//-------------------------------------------------------------- void testApp::draw(){ // draw vertices glColor3f(0.63f, 0.63f, 0.63f); for ( int i = 0; i < physics->numberOfParticles(); ++i ) { Particle* v = physics->getParticle( i ); ofCircle( v->mPos, NODE_SIZE/2.0f ); } // draw springs ofSetColor(ofColor::black ); for ( int i = 0; i < physics->numberOfSprings(); ++i ) { Spring* e = physics->getSpring( i ); Particle* a = e->getOneEnd(); Particle* b = e->getTheOtherEnd(); ofLine( a->mPos, b->mPos ); } }
bool Feeler :: feelTowards( const vec2 & colliderPos, float minDist, float force ){ bool activated = false; for(int i = 1; i < springs.size(); i++){ float alongRatio = (float)i / springs.size(); Spring * spring = springs.at(i); if( glm::distance( spring->global, colliderPos ) < minDist ) { activated = true; } if( activated ) { spring->addForce( (colliderPos - spring->global) * force * alongRatio ); } } return activated; }
void AGWorm::move(){ if(randFloat(1.f) < nervosismo){ dest += *new Vec3f(randFloat(-rSpeed,rSpeed),randFloat(-rSpeed,rSpeed),randFloat(-rSpeed,rSpeed)); } pos.x += (dest.x - pos.x) * rDamp; pos.y += (dest.y - pos.y) * rDamp; pos.z += (dest.z - pos.z) * rDamp; nodes.at(0).setPos(pos); //for (vector<Spring*> s) for(int i = 0; i < springs.size(); i++) { Spring s = springs.at(i); s.step(); } for(int i = 0; i < nodes.size(); i++) { Node n = nodes.at(i); n.step(); } // This call was not part of the original Processing/AGWorm rotate(nodes.begin(), nodes.end()-1, nodes.end()); }
void wave::setupSpring(){ points.clear(); springs.clear(); for (int i = 0; i < amount; i++) { Spring spring; spring.setup( strength, restLength, invMass); springs.push_back( spring ); Point_ point; float step = width/(amount*1.0-1.0); ofVec2f pos(i*step , ypos); point.p = pos; point.pp = pos; if(i == 0 || i == amount-1 ){ point.isFixed = true; }else{ point.isFixed = false; } points.push_back(point); } }
void Demo::setupVerlet() { physic.integrator = new Verlet(); mouse.setMass(10); //add gravity physic.vBehaviour.push_back(&force); // add integrator physic.integrator = new Verlet(); //weave particles NUM_PARTICLES = CLOTH_ROW * CLOTH_COLS; physic.particles = new Particle[NUM_PARTICLES]; short sx = (ofGetWindowWidth() - (CLOTH_COLS * CLOTH_SIZE)) * 0.5; short sy = (ofGetWindowHeight() - (CLOTH_ROW * CLOTH_SIZE)) * 0.5; short x, y, count = 0; // add vector for the verlet vector< vector<Particle> > vParticle; for (x = 0; x < CLOTH_COLS; x++) { vector<Particle> row; for (y = 0; y < CLOTH_ROW; y++) { physic.particles[count].fixed = (y == 0) ? true : false; physic.particles[count].pos = new Vector(); physic.particles[count].acc = new Vector(); physic.particles[count].vel = new Vector(); physic.particles[count].moveTo( (sx + x * CLOTH_SIZE), (sy + y * CLOTH_SIZE) ); physic.particles[count].setRadius(DOT_SIZE); physic.particles[count].setMass(10); row.push_back(physic.particles[count]); count++; } vParticle.push_back(row); } count = 0; //cout << vParticle.size() << " " << vParticle[0].size() << endl; for (x = 0; x < vParticle.size(); x++) { for (y = 0; y < vParticle[x].size(); y++) { if (x > 0) { Spring spring; spring.setup( physic.particles[count], vParticle[x-1][y], CLOTH_SIZE, 0.5 ); physic.vSpring.push_back(spring); } if (y > 0) { Spring spring; spring.setup( physic.particles[count], vParticle[x][y-1], CLOTH_SIZE, 0.5 ); physic.vSpring.push_back(spring); } count++; } } Spring spring; spring.setup(mouse, vParticle[CLOTH_COLS/2][CLOTH_ROW/2], 4, 4); physic.vSpring.push_back(spring); //vParticle[0][0].fixed = true; // vParticle[CLOTH_COLS - 1][0].fixed = true; }
void Garment::setSpringAll(){ int allClothLength = allCloth.size(); int clothLength =0; float tmpx; float tmpy; float tmpz; for(int i = 0;i < allClothLength; i ++){ clothLength = allCloth.at(i).getVectorMass()->size(); for(int j = 0;j < clothLength;j ++){ for(int k = 0;k < clothLength;k ++){ if(j == k){ continue; } tmpx = allCloth.at(i).getVectorMass()->at(j)->x - allCloth.at(i).getVectorMass()->at(k)->x; if(tmpx > STRUCTLENGTH * 2.0f + STRUCTLENGTH * 2.0f / 10.0f){ continue; } tmpy = allCloth.at(i).getVectorMass()->at(j)->y - allCloth.at(i).getVectorMass()->at(k)->y; if(tmpy > STRUCTLENGTH * 2.0f + STRUCTLENGTH * 2.0f / 10.0f){ continue; } tmpz = allCloth.at(i).getVectorMass()->at(j)->z - allCloth.at(i).getVectorMass()->at(k)->z; if(tmpz > STRUCTLENGTH * 2.0f + STRUCTLENGTH * 2.0f / 10.0f){ continue; } float tmplength = sqrt( tmpx * tmpx + tmpy * tmpy + tmpz * tmpz ); if(tmplength < STRUCTLENGTH + STRUCTLENGTH / 10.0f){ Spring *tmpSring = new Spring(1,allCloth.at(i).getVectorMass()->at(j)); tmpSring->setConnectedMass(allCloth.at(i).getVectorMass()->at(k)); allCloth.at(i).getVectorMass()->at(j)->massSpring.push_back(tmpSring); }else if(tmplength < STRUCTLENGTH * 1.4142135623f + STRUCTLENGTH * 1.4142135623f / 10.0f){ Spring *tmpSring = new Spring(2,allCloth.at(i).getVectorMass()->at(j)); tmpSring->setConnectedMass(allCloth.at(i).getVectorMass()->at(k)); allCloth.at(i).getVectorMass()->at(j)->massSpring.push_back(tmpSring); }else if(tmplength < STRUCTLENGTH * 2.0f + STRUCTLENGTH * 2.0f / 10.0f){ Spring *tmpSring = new Spring(3,allCloth.at(i).getVectorMass()->at(j)); tmpSring->setConnectedMass(allCloth.at(i).getVectorMass()->at(k)); allCloth.at(i).getVectorMass()->at(j)->massSpring.push_back(tmpSring); } } } } }
/**读入缝*/ bool Garment::readSeam(char * loc){ int sizeCloth = allCloth.size()/2; for(int i = 0;i < sizeCloth/2; i ++){ for(int j = 0; j < allCloth.at(i).massCloth.size();j ++){ allCloth.at(i*2).getVectorMass()->at(j)->seamForce = Force(0,0,-SEAMFORCE); allCloth.at(i*2 + 1).getVectorMass()->at(j)->seamForce = Force(0,0,SEAMFORCE); // } } for(int i = 0;i < sizeCloth; i ++){ for(int j = 0; j < allCloth.at(2*i).massSeam.size();j ++){ allCloth.at(2*i).massSeam.at(j)->seamMassPoint=(allCloth.at(2*i+1).massSeam.at(j)); allCloth.at(2*i).massSeam.at(j)->seamForce = Force(0,0,-SEAMFORCE); allCloth.at(2*i+1).massSeam.at(j)->seamMassPoint=(allCloth.at(2*i).massSeam.at(j)); allCloth.at(2*i+1).massSeam.at(j)->seamForce = Force(0,0,SEAMFORCE); Spring *tmpSring = new Spring(1,allCloth.at(2*i).massSeam.at(j)); tmpSring->setConnectedMass(allCloth.at(2*i+1).massSeam.at(j)); allCloth.at(2*i).massSeam.at(j)->massSpring.push_back(tmpSring); allCloth.at(2*i).massSeam.at(j)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(2*i+1).massSeam.at(j)); tmpSring->setConnectedMass(allCloth.at(2*i).massSeam.at(j)); allCloth.at(2*i+1).massSeam.at(j)->massSpring.push_back(tmpSring); allCloth.at(2*i+1).massSeam.at(j)->massSpring.push_back(tmpSring); // } } //for(int i = 0;i < sizeCloth; i ++){ // for(int j = 0; j < allCloth.at(2*i).massSeam1.size();j ++){ // allCloth.at(2*i).massSeam1.at(j)->setSeamPoint(allCloth.at(2*i+1).massSeam1.at(j)); // allCloth.at(2*i+1).massSeam1.at(j)->setSeamPoint(allCloth.at(2*i).massSeam1.at(j)); // } //} int sizearmwidth = allCloth.at(2).massSeam1.size(); int bodysize =allCloth.at(0).massSeam1.size()/2; for(int i = 0;i < sizearmwidth; i ++){ /*allCloth.at(0).massSeam1.at(i)->setSeamPoint(allCloth.at(2).massSeam1.at(i)); allCloth.at(0).massSeam1.at(i+bodysize)->setSeamPoint(allCloth.at(4).massSeam1.at(i));*/ Spring *tmpSring = new Spring(1,allCloth.at(0).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(2).massSeam1.at(i)); allCloth.at(0).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(0).massSeam1.at(i)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(0).massSeam1.at(i+bodysize)); tmpSring->setConnectedMass(allCloth.at(4).massSeam1.at(i)); allCloth.at(0).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); allCloth.at(0).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); /*allCloth.at(2).massSeam1.at(i)->setSeamPoint(allCloth.at(0).massSeam1.at(i)); allCloth.at(4).massSeam1.at(i)->setSeamPoint(allCloth.at(0).massSeam1.at(i+bodysize));*/ tmpSring = new Spring(1,allCloth.at(2).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(0).massSeam1.at(i)); allCloth.at(2).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(2).massSeam1.at(i)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(4).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(0).massSeam1.at(i+bodysize)); allCloth.at(4).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(4).massSeam1.at(i)->massSpring.push_back(tmpSring); /*allCloth.at(1).massSeam1.at(i)->setSeamPoint(allCloth.at(3).massSeam1.at(i)); allCloth.at(1).massSeam1.at(i+bodysize)->setSeamPoint(allCloth.at(5).massSeam1.at(i));*/ tmpSring = new Spring(1,allCloth.at(1).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(3).massSeam1.at(i)); allCloth.at(1).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(1).massSeam1.at(i)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(1).massSeam1.at(i+bodysize)); tmpSring->setConnectedMass(allCloth.at(5).massSeam1.at(i)); allCloth.at(1).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); allCloth.at(1).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); /*allCloth.at(3).massSeam1.at(i)->setSeamPoint(allCloth.at(1).massSeam1.at(i)); allCloth.at(5).massSeam1.at(i)->setSeamPoint(allCloth.at(1).massSeam1.at(i+bodysize));*/ tmpSring = new Spring(1,allCloth.at(3).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(1).massSeam1.at(i)); allCloth.at(3).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(3).massSeam1.at(i)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(5).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(1).massSeam1.at(i+bodysize)); allCloth.at(5).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(5).massSeam1.at(i)->massSpring.push_back(tmpSring); } //sizearmwidth = bodysize -sizearmwidth; for(int i = sizearmwidth;i < bodysize; i ++){ allCloth.at(0).massSeam1.at(i)->setSeamPoint(allCloth.at(1).massSeam1.at(i)); allCloth.at(0).massSeam1.at(i+bodysize)->setSeamPoint(allCloth.at(1).massSeam1.at(i+bodysize)); allCloth.at(0).massSeam1.at(i)->seamForce = Force(0,0,-SEAMFORCE); allCloth.at(0).massSeam1.at(i+bodysize)->seamForce = Force(0,0,-SEAMFORCE); allCloth.at(1).massSeam1.at(i)->setSeamPoint(allCloth.at(0).massSeam1.at(i)); allCloth.at(1).massSeam1.at(i+bodysize)->setSeamPoint(allCloth.at(0).massSeam1.at(i+bodysize)); allCloth.at(1).massSeam1.at(i)->seamForce = Force(0,0,SEAMFORCE); allCloth.at(1).massSeam1.at(i+bodysize)->seamForce = Force(0,0,SEAMFORCE); Spring *tmpSring = new Spring(1,allCloth.at(0).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(1).massSeam1.at(i)); allCloth.at(0).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(0).massSeam1.at(i)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(0).massSeam1.at(i+bodysize)); tmpSring->setConnectedMass(allCloth.at(1).massSeam1.at(i+bodysize)); allCloth.at(0).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); allCloth.at(0).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(1).massSeam1.at(i)); tmpSring->setConnectedMass(allCloth.at(0).massSeam1.at(i)); allCloth.at(1).massSeam1.at(i)->massSpring.push_back(tmpSring); allCloth.at(1).massSeam1.at(i)->massSpring.push_back(tmpSring); tmpSring = new Spring(1,allCloth.at(1).massSeam1.at(i+bodysize)); tmpSring->setConnectedMass(allCloth.at(0).massSeam1.at(i+bodysize)); allCloth.at(1).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); allCloth.at(1).massSeam1.at(i+bodysize)->massSpring.push_back(tmpSring); } return true; }
void World::CalculateViscoElasticity() { for(int i=0; i<NumParticles; ++i) { Particle &p = mParticles[i]; int neighbourEnd = p.mNeighbourListIndex + p.mNeighbourCount; for(int ni=p.mNeighbourListIndex; ni<neighbourEnd; ++ni) { Neighbour &n = mNeighbourhood.GetNeighbour(ni); Particle *np = n.mParticle; if(!mSpringFlags.IsSet(p.mIndex, np->mIndex)) { mSpringFlags.Set(p.mIndex, np->mIndex); Spring *s = mSprings.Alloc(); if(s != null) { s->mP0 = &p; s->mP1 = np; s->mRestLength = SmoothingRadius; s->mCoefficient = SpringCoefficient; } } } } Spring *n; for(Spring *s = mSprings.mBusyList.head; s != null; s = n) { n = s->next; float td = YieldRatio * s->mRestLength; float dist = (s->mP0->mPosition - s->mP1->mPosition).length(); if(dist > s->mRestLength + td) { s->mRestLength += deltaTimeScaled * Plasticity * (dist - s->mRestLength - td); if(s->mRestLength > SmoothingRadius) { mSpringFlags.Clear(s->mP0->mIndex, s->mP1->mIndex); mSprings.mBusyList.Remove(s); mSprings.mFreeList.AddTail(s); } } else if (dist < s->mRestLength - td) { s->mRestLength -= deltaTimeScaled * Plasticity * (s->mRestLength - td - dist ); } } for(Spring *s = mSprings.mBusyList.head; s != null; s = s->next) { Vec2 displacement = s->CalculateForce() * (1.0f - s->mRestLength / SmoothingRadius) * deltaTimeScaledSquared; s->mP0->mPosition += displacement; s->mP1->mPosition -= displacement; } }
void Seaweed::animate(int reset) { if(reset) { particles = vector<Particle *>(); springs = vector<Spring *>(); createSystemScene(); } //======== 1. Compute all forces // map to accumulate the forces to apply on each particle map<const Particle *, Vec> forces; // weights vector<Particle *>::iterator itP; for (itP = particles.begin(); itP != particles.end(); ++itP) { Particle *p = *itP; forces[p] = gravity * p->getMass(); forces[p] += push * p->getRadius() * p->getRadius()* 3.14 * 103.2 ; if(p->getVelocity().y < 0) forces[p] -= wave; else forces[p] -= wave; forces[p] -= mediumViscosity * p->getVelocity(); // Damping force applied by the viscosity // viscosity is applied against the velocity and to all particles } // damped springs vector<Spring *>::iterator itS; for (itS = springs.begin(); itS != springs.end(); ++itS) { Spring *s = *itS; Vec f12 = s->getCurrentForce(); forces[s->getParticle1()] += f12; forces[s->getParticle2()] -= f12; // opposite force } //======== 2. Integration scheme // Here the velocity is changed... But... Need it to be cyclic for (itP = particles.begin(); itP != particles.end(); ++itP) { Particle *p = *itP; p->incrVelocity(forces[p] * p->getInvMass() * dt); } // update particles positions for (itP = particles.begin(); itP != particles.end(); ++itP) { Particle *p = *itP; // q = q + dt * v, explicit euler. Vec origin = Vec(0.0,0.30,0.0); Vec upper = Vec(1.0,0.70,2.0); if( ( /*->getPosition().x < origin.x || */p->getPosition().y < origin.y /*|| p->getPosition().z < origin.z */) || (/*p->getPosition().x > upper.x || */p->getPosition().y > upper.y/* || p->getPosition().z > upper.z */) ) { float dist = ( p->getPosition().y - origin.y)*( p->getPosition().y - origin.y); p->incrVelocity(-p->getVelocity() * resist * dist); //Vec veltmp = - p->getVelocity() * resist; //p->setVelocity(veltmp); } p->incrPosition(dt * p->getVelocity()); } //======== 3. Collisions //TO DO: discuss multi-collisions and order! for (itP = particles.begin(); itP != particles.end(); ++itP) { collisionParticleGround(*itP); } bool collide = true; while(collide) { collide = false; for(unsigned int i = 1; i < particles.size(); ++i) { Particle *p1 = particles[i - 1]; Particle *p2 = particles[i]; collide |= collisionParticleParticle(p1, p2); } } }