Example #1
0
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;
}
Example #2
0
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;
}