void Boid::PreUpdate() { // find nearest boids BoidFriend boids[5]; int count = 0; FindClosest(boids, count, 5); // avoid walls AvoidWalls(); // update anger if (count != 0) { float anger = 0.f; for (int i = 0; i != count; ++i) anger += boids[i].boid->m_Anger; anger /= count; // slowly adjust towards group anger if (anger > m_Anger) m_Anger += g_FrameTime * count; else m_Anger -= g_FrameTime * 0.5f; } m_Anger += Rand(0.f, 0.05f) * g_FrameTime; m_Anger = Clamp(m_Anger, 0.f, 1.f); // calculate flocking steering AddForce(Flock(boids, count)); // attack if angry, otherwise flock and wander if (m_Anger > 0.5f) { float t = (m_Anger - 0.5f) * 2.f; AddForce(Attack() * t); } else AddForce(Wander()); }
void BoidsManager::update() // FlightStep(); { Velocity goCenterVel; Velocity goAttractVel; Velocity matchNeighborVel; Velocity avoidWallsVel; Velocity avoidNeighborVel; float avoidNeighborSpeed; const Velocity zeroVel = {0.0, 0.0}; short i; m_centerPt = FindFlockCenter(); // save position and velocity for (i = 0; i < m_numBoids; i++) { m_boids[i].oldPos.x = m_boids[i].newPos.x; m_boids[i].oldPos.y = m_boids[i].newPos.y; m_boids[i].oldDir.x = m_boids[i].newDir.x; m_boids[i].oldDir.y = m_boids[i].newDir.y; } for (i = 0; i < m_numBoids; i++) { // get all velocity components if (m_numNeighbors > 0) { avoidNeighborSpeed = MatchAndAvoidNeighbors(i,&matchNeighborVel, &avoidNeighborVel); } else { matchNeighborVel = zeroVel; avoidNeighborVel = zeroVel; avoidNeighborSpeed = 0; } goCenterVel = SeekPoint(i, m_centerPt); goAttractVel = SeekPoint(i, m_attractPt); avoidWallsVel = AvoidWalls(i); // compute resultant velocity using weights and inertia m_boids[i].newDir.x = m_inertiaFactor * (m_boids[i].oldDir.x) + (m_centerWeight * goCenterVel.x + m_attractWeight * goAttractVel.x + m_matchWeight * matchNeighborVel.x + m_avoidWeight * avoidNeighborVel.x + m_wallsWeight * avoidWallsVel.x) / m_inertiaFactor; m_boids[i].newDir.y = m_inertiaFactor * (m_boids[i].oldDir.y) + (m_centerWeight * goCenterVel.y + m_attractWeight * goAttractVel.y + m_matchWeight * matchNeighborVel.y + m_avoidWeight * avoidNeighborVel.y + m_wallsWeight * avoidWallsVel.y) / m_inertiaFactor; // normalize velocity so its length is unity NormalizeVelocity(&(m_boids[i].newDir)); // set to avoidNeighborSpeed bounded by minSpeed and maxSpeed if ((avoidNeighborSpeed >= m_minSpeed) && (avoidNeighborSpeed <= m_maxSpeed)) m_boids[i].speed = avoidNeighborSpeed; else if (avoidNeighborSpeed > m_maxSpeed) m_boids[i].speed = m_maxSpeed; else m_boids[i].speed = m_minSpeed; // calculate new position, applying speedupFactor m_boids[i].newPos.x += m_boids[i].newDir.x * m_boids[i].speed * m_speedupFactor; m_boids[i].newPos.y += m_boids[i].newDir.y * m_boids[i].speed * m_speedupFactor; } }
void FlightStep(t_jit_boids2d *flockPtr) { double goCenterVel[2]; double goAttractVel[2]; double matchNeighborVel[2]; double avoidWallsVel[2]; double avoidNeighborVel[2]; double avoidNeighborSpeed; const double zeroVel[2] = {0.0, 0.0}; long i; //now modifies flockPtr->centgerPt within the function instead of returning a value FindFlockCenter(flockPtr); for (i = 0; i < flockPtr->number; i++) { // save position and velocity flockPtr->boid[i].oldPos[x] = flockPtr->boid[i].newPos[x]; flockPtr->boid[i].oldPos[y] = flockPtr->boid[i].newPos[y]; //flockPtr->boid[i].oldPos[z] = flockPtr->boid[i].newPos[z]; flockPtr->boid[i].oldDir[x] = flockPtr->boid[i].newDir[x]; flockPtr->boid[i].oldDir[y] = flockPtr->boid[i].newDir[y]; //flockPtr->boid[i].oldDir[z] = flockPtr->boid[i].newDir[z]; } for (i = 0; i < flockPtr->number; i++) { if (flockPtr->neighbors > 0) { // get all velocity components avoidNeighborSpeed = MatchAndAvoidNeighbors(flockPtr, i, matchNeighborVel, avoidNeighborVel); } else { matchNeighborVel[x] = zeroVel[x]; matchNeighborVel[y] = zeroVel[y]; //matchNeighborVel[z] = zeroVel[z]; avoidNeighborVel[x] = zeroVel[x]; avoidNeighborVel[y] = zeroVel[y]; //avoidNeighborVel[z] = zeroVel[z]; avoidNeighborSpeed = 0; } //velocities passed in as argument SeekPoint(flockPtr, i, flockPtr->centerPt, goCenterVel); SeekPoint(flockPtr, i, flockPtr->attractpt, goAttractVel); AvoidWalls(flockPtr, i, avoidWallsVel); // compute resultant velocity using weights and inertia flockPtr->boid[i].newDir[x] = flockPtr->inertia * (flockPtr->boid[i].oldDir[x]) + (flockPtr->center * goCenterVel[x] + flockPtr->attract * goAttractVel[x] + flockPtr->match * matchNeighborVel[x] + flockPtr->avoid * avoidNeighborVel[x] + flockPtr->repel * avoidWallsVel[x]) / flockPtr->inertia; flockPtr->boid[i].newDir[y] = flockPtr->inertia * (flockPtr->boid[i].oldDir[y]) + (flockPtr->center * goCenterVel[y] + flockPtr->attract * goAttractVel[y] + flockPtr->match * matchNeighborVel[y] + flockPtr->avoid * avoidNeighborVel[y] + flockPtr->repel * avoidWallsVel[y]) / flockPtr->inertia; /*flockPtr->boid[i].newDir[z] = flockPtr->inertia * (flockPtr->boid[i].oldDir[z]) + (flockPtr->center * goCenterVel[z] + flockPtr->attract * goAttractVel[z] + flockPtr->match * matchNeighborVel[z] + flockPtr->avoid * avoidNeighborVel[z] + flockPtr->repel * avoidWallsVel[z]) / flockPtr->inertia;*/ NormalizeVelocity(flockPtr->boid[i].newDir); // normalize velocity so its length is unity // set to avoidNeighborSpeed bounded by minspeed and maxspeed if ((avoidNeighborSpeed >= flockPtr->minspeed) && (avoidNeighborSpeed <= flockPtr->maxspeed)) flockPtr->boid[i].speed = avoidNeighborSpeed; else if (avoidNeighborSpeed > flockPtr->maxspeed) flockPtr->boid[i].speed = flockPtr->maxspeed; else flockPtr->boid[i].speed = flockPtr->minspeed; // calculate new position, applying speed flockPtr->boid[i].newPos[x] += flockPtr->boid[i].newDir[x] * flockPtr->boid[i].speed * (flockPtr->speed / 100.0); flockPtr->boid[i].newPos[y] += flockPtr->boid[i].newDir[y] * flockPtr->boid[i].speed * (flockPtr->speed / 100.0); //flockPtr->boid[i].newPos[z] += flockPtr->boid[i].newDir[z] * flockPtr->boid[i].speed * (flockPtr->speed / 100.0); } }