root/native_client_sdk/src/examples/demo/flock/goose.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GOOSE_H_
#define GOOSE_H_

#include <vector>
#include "ppapi/cpp/rect.h"

#include "vector2.h"

// A Goose.  Each goose has a location and a velocity.  Implements the
// flocking algortihm described here:
// http://processingjs.org/learning/topic/flocking with references to
// http://harry.me/2011/02/17/neat-algorithms---flocking.
class Goose {
 public:
  // Initialize a Goose at location (0, 0) no velocity.
  Goose();

  // Initialize a Goose at the given location with the specified velocity.
  Goose(const Vector2& location, const Vector2& velocity);

  // Run one tick of the simulation.  Compute a new acceleration based on the
  // flocking algorithm (see Goose.flock()) and update the goose's location
  // by integrating acceleration and velocity.
  // @param geese The list of all the geese in the flock.
  // @param  attractors The list of attractors.  Geese have affinity for these
  //     points.
  // @param flockBox The geese will stay inside of this box.  If the flock_box
  //     is empty, the geese don't have boundaries.
  void SimulationTick(const std::vector<Goose>& geese,
                      const std::vector<Vector2>& attractors,
                      const pp::Rect& flock_box);

  // Implement the flocking algorithm in five steps:
  //  1. Compute the separation component,
  //  2. Compute the alignment component,
  //  3. Compute the cohesion component.
  //  4. Compute the effect of the attractors and blend this in with the
  //     cohesion component.
  //  5. Create a weighted sum of the three components and use this as the
  //     new acceleration for the goose.
  // This is an O(n^2) version of the algorithm.  There are ways to speed this
  // up using spatial coherence techniques, but this version is much simpler.
  // @param geese The list of all the neighbouring geese (in this
  //     implementation, this is all the geese in the flock).
  // @param  attractors The list of attractors.  Geese have affinity for these
  //     points.
  // @return The acceleration vector for this goose based on the flocking
  //     algorithm.
  Vector2 DesiredVector(const std::vector<Goose>& geese,
                        const std::vector<Vector2>& attractors);

  // Turn the goose towards a target.  The amount of turning force is clamped
  // to |kMaxTurningForce|.
  // @param target Turn the goose towards this target.
  // @return A vector representing the new direction of the goose.
  Vector2 TurnTowardsTarget(const Vector2& target);

  // Accessors for location and velocoity.
  Vector2 location() const {
    return location_;
  }
  Vector2 velocity() const {
    return velocity_;
  }

 private:
  // Add a neighbouring goose's contribution to the separation mean.  Only
  // consider geese that have moved inside of this goose's personal space.
  // Modifies the separation accumulator |separation| in-place.
  // @param distance The distance from this goose to the neighbouring goose.
  // @param gooseDirection The direction vector from this goose to the
  //     neighbour.
  // @param separation The accumulated separation from all the neighbouring
  //     geese.
  // @param separationCount The current number of geese that have contributed to
  //     the separation component so far.
  // @return The new count of geese that contribute to the separation component.
  //     If the goose under consideration does not contribute, this value is the
  //     same as |separationCount|.
  int32_t AccumulateSeparation(double distance,
                               const Vector2& goose_direction,
                               Vector2* separation, /* inout */
                               int32_t separation_count);

  // Add a neighbouring goose's contribution to the alignment mean.  Alignment
  // is the average velocity of the neighbours. Only consider geese that are
  // within |kNeighbourRadius|.  Modifies the alignment accumulator |alignment|
  // in-place.
  // @param distance The distance from this goose to the neighbouring goose.
  // @param goose The neighbouring goose under consideration.
  // @param alignment The accumulated alignment from all the neighbouring geese.
  // @param alignCount The current number of geese that have contributed to the
  //     alignment component so far.
  // @return The new count of geese that contribute to the alignment component.
  // If the goose under consideration does not contribute, this value is the
  //     same as |alignCount|.
  int32_t AccumulateAlignment(double distance,
                              const Goose& goose,
                              Vector2* alignment, /* inout */
                              int32_t align_count);

  // Add a neighbouring goose's contribution to the cohesion mean.  Cohesion is
  // based on the average location of the neighbours.  The goose attempts to
  // point to this average location.  Only consider geese that are within
  // |kNeighbourRadius|.  Modifies the cohesion accumulator |cohesion| in-place.
  // @param {!number} distance The distance from this goose to the neighbouring
  //     goose.
  // @param {!Goose} goose The neighbouring goose under consideration.
  // @param {!goog.math.Vec2} cohesion The accumulated cohesion from all the
  //     neighbouring geese.
  // @param {!number} cohesionCount The current number of geese that have
  //     contributed to the cohesion component so far.
  // @return {!number} The new count of geese that contribute to the cohesion
  //     component.  If the goose under consideration does not contribute, this
  //     value is the same as |cohesionCount|.
  int32_t AccumulateCohesion(double distance,
                             const Goose& goose,
                             Vector2* cohesion, /* inout */
                             int32_t cohesion_count);

  Vector2 location_;
  Vector2 velocity_;
};

#endif  // GOOSE_H_

/* [<][>][^][v][top][bottom][index][help] */