void PointBehavior::Apply(Boid& boid) { ofVec2f displacement; int count = 0; GameEntityState& boidState = boid.CurrentState(); for (RIterator it = GetRelevant(boid.Senses.EntitiesInRange); !it.End(); ++it) { count++; GameEntity* entity = it.Current(); // use next state if it has already been calculated, otherwise use GameEntityState& entityState = entity->NextState().IsReady ? entity->NextState() : entity->CurrentState(); ofVec2f offset = entityState.Position - boidState.Position; if (offset.length() < Range) { float inverseDistance = Range - offset.length(); offset.normalize(); ofVec2f weight = offset * inverseDistance * (IsAttractive ? 1: -1); displacement += weight; } } if (count <1) return; boid.NextState().Velocity += displacement * this->Factor; }
void FlockingBehavior::Apply(Boid& boid) { float m1 = 1.0f; float m2 = 1.0f; // Modifiers for flocking if (this->AvoidOnly) { m2 = 0.0f; m1 = -0.1f; } // ==================================== // GROUP start ofVec2f group; // AVOID start ofVec2f avoid; // ALIGN start ofVec2f align; int boidCount = 0; ofVec2f offset; GameEntityState& boidState = boid.CurrentState(); // ==================================== for (RIterator it = GetRelevant(boid.Senses.EntitiesInRange); !it.End(); ++it) { boidCount++; GameEntity* entity = it.Current(); // use next state if it has already been calculated, otherwise use GameEntityState& entityState = entity->NextState().IsReady ? entity->NextState() : entity->CurrentState(); offset = entityState.Position - boidState.Position; // ................... // GROUP iter group += entityState.Position; // ................... // AVOID iter if (offset.length() < AvoidDistance) { float inverseDistance = AvoidDistance - offset.length(); // The further in the more effect we want it to have on the final heading // Normalize vector to get the direction offset.normalize(); // Multiply it by the inverse distance to give it magnitude // This gives us the vector from the edge of the avoidance circle to the boid b // Thus the closer boid b is to this boid the more wieght it will have on the avoidance heading ofVec2f weightb = offset * inverseDistance; avoid -= weightb; } // ................... // ALIGN iter align += entityState.Velocity; } if (boidCount < 1) return; // ==================================== // GROUP end group /= boidCount; group = (group - boidState.Position) * GroupFactor; // AVOID end avoid *= 0.1f; // ALIGN end align /= boidCount; align = (align - boidState.Velocity) * AlignFactor; // ==================================== // RESULT ofVec2f adjustment = ((m1*group) + avoid + (m2*align)); //if (adjustment.length() > boid.CurrentState().Direction.length()) // adjustment.normalize();// *= boid.CurrentState().Direction.length(); boid.NextState().Velocity += adjustment; }