1 #ifndef ELEMENT_BOIDS_H
2 #define ELEMENT_BOIDS_H
114 typedef typename CC::ATOM_TYPE T;
115 typedef typename CC::PARAM_CONFIG P;
116 enum { R = P::EVENT_WINDOW_RADIUS };
123 Vector() : x(0), y(0) { }
128 FXP16 GetX()
const {
return x; }
130 FXP16 GetY()
const {
return y; }
133 f.Printf(
"(%06x,%06x)",x.asInt(),y.asInt());
136 friend FXP16 GetDistSq(
const Vector & v1,
const Vector & v2) {
137 return (v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y);
140 friend Vector operator+(
const Vector & v1,
const Vector & v2) {
141 return Vector(v1.x+v2.x,v1.y+v2.y);
143 friend Vector operator-(
const Vector & v1) {
144 return Vector(-v1.x,-v1.y);
146 friend Vector operator-(
const Vector & v1,
const Vector & v2) {
149 friend FXP16 operator*(
const Vector & v1,
const Vector v2) {
150 return v1.x*v2.x+v1.y*v2.y;
152 friend Vector operator*(
const FXP16 num,
const Vector & v1) {
153 return Vector(v1.x*num,v1.y*num);
155 friend Vector operator*(
const Vector & v1,
const FXP16 num) {
158 friend Vector operator/(
const Vector & v1,
const FXP16 num) {
162 Vector & operator=(
const Vector & v1) {
168 Vector & operator+=(
const Vector & v1) {
173 Vector & operator-=(
const Vector & v1) {
178 Vector & operator*=(
const FXP16 num) {
183 Vector & operator/=(
const FXP16 num) {
190 template <u32 TVBITS>
191 static u32 toSignMag(
FXP16 value) {
192 const u32 SIGN_BIT = 1<<(TVBITS-1);
193 const u32 MAX = SIGN_BIT-1;
201 u32 val = (u32) value;
205 template <u32 TVBITS>
206 static FXP16 fromSignMag(
const u32 value) {
207 const u32 SIGN_BIT = 1<<(TVBITS-1);
208 const u32 MASK = SIGN_BIT-1;
209 FXP16 val = value&MASK;
210 if (value & SIGN_BIT)
215 template <u32 TVBITS>
216 static u32 toTinyVector(
const Vector v) {
217 u32 x = toSignMag<TVBITS>(v.x);
218 u32 y = toSignMag<TVBITS>(v.y);
219 return (x<<TVBITS)|y;
222 template <u32 TVBITS>
223 static Vector toVector(
const u32 bits) {
224 const u32 MASK = (1<<TVBITS)-1;
226 FXP16 x = fromSignMag<TVBITS>((bits>>TVBITS)&MASK);
227 FXP16 y = fromSignMag<TVBITS>(bits&MASK);
233 static const u32 TYPE = 0xbd;
234 static const u32 TYPE_BITS = 8;
235 static const u32 TYPE_MASK = (1<<TYPE_BITS)-1;
236 static bool IsBoidType(u32 type) {
237 return (type&TYPE_MASK)==TYPE;
240 static const u32 BITS_PER_DIM = 4;
242 static const u32 STATE_HEADING_IDX = 0;
243 static const u32 STATE_HEADING_LEN = 2 * BITS_PER_DIM;
244 static const u32 STATE_BITS = STATE_HEADING_IDX + STATE_HEADING_LEN;
248 Vector GetHeading(
const T &atom)
const {
249 if (!IsBoidType(atom.GetType()))
251 return toVector<BITS_PER_DIM>(atom.GetStateField(STATE_HEADING_IDX,STATE_HEADING_LEN));
254 void SetHeading(
const T &atom,
const Vector v)
const {
255 if (!IsBoidType(atom.GetType()))
257 atom.SetStateField(STATE_HEADING_IDX,STATE_HEADING_LEN,toTinyVector<BITS_PER_DIM>(v));
265 const FXP16 MAX_DIST = R;
266 const FXP16 MAX_DIST_WGT = R;
267 const FXP16 WGT_PER_DIST = MAX_DIST_WGT / MAX_DIST;
271 const SPoint sp = md.GetPoint(idx);
293 FXP16 dist = GetDistSq(spVec,target);
296 weight = MAX_DIST_WGT-dist*WGT_PER_DIST;
302 if (random.
OddsOf(weight,totWgt)) {
312 const double TARGET_SPACING = 1.5;
316 const u32 selfType =
self.GetType();
318 if (!IsBoidType(selfType))
337 const SPoint sp = md.GetPoint(idx);
340 const u32 otherType = other.GetType();
343 if (random.
OneIn(++resCount)) resAt = sp;
347 if (otherType != selfType)
continue;
353 Vector theirHead = GetHeading(other);
355 avgHeading += theirHead;
356 avgPosition += Vector(sp);
361 if (countNgbr > 0 && countNgbr < 3 && resCount > 0) {
368 if (countNgbr == 0) {
372 if (random.
OneIn(3)) {
376 }
else if (countNgbr == 1 && minDist > TARGET_SPACING) {
378 SPoint dest = PickPossibleDestination(window,avgPosition,random);
384 avgHeading /= countNgbr;
385 avgPosition /= countNgbr;
u32 GetFirstIndex(const u32 radius) const
Definition: MDist.h:112
Definition: Element_Boids.h:111
void Diffuse(EventWindow< CC > &window) const
Definition: Element.tcc:73
Definition: Element_Empty.h:41
u32 GetLastIndex(const u32 radius) const
Definition: MDist.h:129
void SetCenterAtom(const T &atom)
Definition: EventWindow.h:220
virtual void Behavior(EventWindow< CC > &window) const
Definition: Element_Boids.h:310
bool OneIn(u32 odds)
Definition: Random.h:96
T GetY() const
Definition: Point.tcc:40
Random & GetRandom()
Definition: EventWindow.h:122
const T & GetRelativeAtom(const SPoint &offset) const
Definition: EventWindow.tcc:26
u32 GetManhattanLength() const
Definition: Point.tcc:46
bool OddsOf(u32 thisMany, u32 outOfThisMany)
Definition: Random.h:183
const T & GetCenterAtom() const
Definition: EventWindow.h:209
virtual const T & GetDefaultAtom() const
Definition: Element.h:382
Definition: ByteSink.h:47
u32 GetMaximumLength() const
Definition: Point.tcc:52
static MDist< R > & get()
Definition: MDist.tcc:193
Definition: Element_Res.h:48
Definition: ElementTable.h:43
bool SetRelativeAtom(const SPoint &offset, const T &atom)
Definition: EventWindow.tcc:15
void SwapAtoms(const SPoint &locA, const SPoint &locB)
Definition: EventWindow.tcc:40
T GetX() const
Definition: Point.tcc:34