From 7cd2126e7c4fe37c0ef6291d2aeb954ad239013a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 23 Nov 2010 00:58:58 +0000 Subject: libdir-ified boids svn path=/trunk/externals/boids/; revision=14504 --- Makefile | 332 ++++++++ README.txt | 25 + boids-meta.pd | 9 + boids.readme.txt | 25 - boids2d-help.pd | 732 +++++++++++++++++ boids2d.c | 962 ++++++++++++++++++++++ boids2d/boids2d-help.pd | 732 ----------------- boids2d/boids2d.c | 962 ---------------------- boids2d/makefile | 92 --- boids3d-help.pd | 2101 +++++++++++++++++++++++++++++++++++++++++++++++ boids3d.c | 956 +++++++++++++++++++++ boids3d/boids3d-help.pd | 2101 ----------------------------------------------- boids3d/boids3d.c | 956 --------------------- boids3d/makefile | 92 --- debian/changelog | 5 + debian/compat | 1 + debian/control | 31 + debian/copyright | 25 + debian/gbp.conf | 7 + debian/links | 3 + debian/rules | 17 + debian/source/format | 1 + debian/watch | 2 + 23 files changed, 5209 insertions(+), 4960 deletions(-) create mode 100644 Makefile create mode 100644 README.txt create mode 100644 boids-meta.pd delete mode 100644 boids.readme.txt create mode 100644 boids2d-help.pd create mode 100644 boids2d.c delete mode 100644 boids2d/boids2d-help.pd delete mode 100644 boids2d/boids2d.c delete mode 100644 boids2d/makefile create mode 100644 boids3d-help.pd create mode 100644 boids3d.c delete mode 100644 boids3d/boids3d-help.pd delete mode 100644 boids3d/boids3d.c delete mode 100644 boids3d/makefile create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/gbp.conf create mode 100644 debian/links create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/watch diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7c50ad2 --- /dev/null +++ b/Makefile @@ -0,0 +1,332 @@ +## Pd library template version 1.0.6 +# For instructions on how to use this template, see: +# http://puredata.info/docs/developer/MakefileTemplate +LIBRARY_NAME = boids + +# add your .c source files, one object per file, to the SOURCES +# variable, help files will be included automatically +SOURCES = boids2d.c boids3d.c + +# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will +# be included automatically +PDOBJECTS = + +# example patches and related files, in the 'examples' subfolder +EXAMPLES = + +# manuals and related files, in the 'manual' subfolder +MANUAL = + +# if you want to include any other files in the source and binary tarballs, +# list them here. This can be anything from header files, test patches, +# documentation, etc. README.txt and LICENSE.txt are required and therefore +# automatically included +EXTRA_DIST = + + + +#------------------------------------------------------------------------------# +# +# things you might need to edit if you are using other C libraries +# +#------------------------------------------------------------------------------# + +# -I"$(PD_INCLUDE)/pd" supports the header location for 0.43 +CFLAGS = -I"$(PD_INCLUDE)/pd" -Wall -W -g +LDFLAGS = +LIBS = + +#------------------------------------------------------------------------------# +# +# you shouldn't need to edit anything below here, if we did it right :) +# +#------------------------------------------------------------------------------# + +# get library version from meta file +LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd) + +CFLAGS += -DPD -DVERSION='"$(LIBRARY_VERSION)"' + +PD_INCLUDE = $(PD_PATH)/include +# where to install the library, overridden below depending on platform +prefix = /usr/local +libdir = $(prefix)/lib +pkglibdir = $(libdir)/pd-externals +objectsdir = $(pkglibdir) + +INSTALL = install +INSTALL_PROGRAM = $(INSTALL) -p -m 644 +INSTALL_DATA = $(INSTALL) -p -m 644 +INSTALL_DIR = $(INSTALL) -p -m 755 -d + +ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \ + $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows) + +DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION) +ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION) + +UNAME := $(shell uname -s) +ifeq ($(UNAME),Darwin) + CPU := $(shell uname -p) + ifeq ($(CPU),arm) # iPhone/iPod Touch + SOURCES += $(SOURCES_iphoneos) + EXTENSION = pd_darwin + OS = iphoneos + PD_PATH = /Applications/Pd-extended.app/Contents/Resources + IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin + CC=$(IPHONE_BASE)/gcc + CPP=$(IPHONE_BASE)/cpp + CXX=$(IPHONE_BASE)/g++ + ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk + IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6 + OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer + CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS) + LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT) + LIBS += -lc + STRIP = strip -x + DISTBINDIR=$(DISTDIR)-$(OS) + else # Mac OS X + SOURCES += $(SOURCES_macosx) + EXTENSION = pd_darwin + OS = macosx + PD_PATH = /Applications/Pd-extended.app/Contents/Resources + OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast +# build universal 32-bit on 10.4 and 32/64 on newer + ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8) + FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4 + else + FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4 + SOURCES += $(SOURCES_iphoneos) + endif + CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include + LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib + # if the 'pd' binary exists, check the linking against it to aid with stripping + LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd) + LIBS += -lc + STRIP = strip -x + DISTBINDIR=$(DISTDIR)-$(OS) +# install into ~/Library/Pd on Mac OS X since /usr/local isn't used much + pkglibdir=$(HOME)/Library/Pd + endif +endif +ifeq ($(UNAME),Linux) + CPU := $(shell uname -m) + SOURCES += $(SOURCES_linux) + EXTENSION = pd_linux + OS = linux + PD_PATH = /usr + OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer + CFLAGS += -fPIC + LDFLAGS += -Wl,--export-dynamic -shared -fPIC + LIBS += -lc + STRIP = strip --strip-unneeded -R .note -R .comment + DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) +endif +ifeq ($(UNAME),GNU) + # GNU/Hurd, should work like GNU/Linux for basically all externals + CPU := $(shell uname -m) + SOURCES += $(SOURCES_linux) + EXTENSION = pd_linux + OS = linux + PD_PATH = /usr + OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer + CFLAGS += -fPIC + LDFLAGS += -Wl,--export-dynamic -shared -fPIC + LIBS += -lc + STRIP = strip --strip-unneeded -R .note -R .comment + DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) +endif +ifeq ($(UNAME),GNU/kFreeBSD) + # Debian GNU/kFreeBSD, should work like GNU/Linux for basically all externals + CPU := $(shell uname -m) + SOURCES += $(SOURCES_linux) + EXTENSION = pd_linux + OS = linux + PD_PATH = /usr + OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer + CFLAGS += -fPIC + LDFLAGS += -Wl,--export-dynamic -shared -fPIC + LIBS += -lc + STRIP = strip --strip-unneeded -R .note -R .comment + DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m) +endif +ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME))) + CPU := $(shell uname -m) + SOURCES += $(SOURCES_cygwin) + EXTENSION = dll + OS = cygwin + PD_PATH = $(cygpath $(PROGRAMFILES))/pd + OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer + CFLAGS += + LDFLAGS += -Wl,--export-dynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" + LIBS += -lc -lpd + STRIP = strip --strip-unneeded -R .note -R .comment + DISTBINDIR=$(DISTDIR)-$(OS) +endif +ifeq (MINGW,$(findstring MINGW,$(UNAME))) + CPU := $(shell uname -m) + SOURCES += $(SOURCES_windows) + EXTENSION = dll + OS = windows + PD_PATH = $(shell cd "$(PROGRAMFILES)"/pd && pwd) + OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer + CFLAGS += -mms-bitfields + LDFLAGS += -s -shared -Wl,--enable-auto-import + LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" -lpd -lwsock32 -lkernel32 -luser32 -lgdi32 + STRIP = strip --strip-unneeded -R .note -R .comment + DISTBINDIR=$(DISTDIR)-$(OS) +endif + +# in case somebody manually set the HELPPATCHES above +HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd) + +CFLAGS += $(OPT_CFLAGS) + + +.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean dist etags $(LIBRARY_NAME) + +all: $(SOURCES:.c=.$(EXTENSION)) + +%.o: %.c + $(CC) $(CFLAGS) -o "$*.o" -c "$*.c" + +%.$(EXTENSION): %.o + $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS) + chmod a-x "$*.$(EXTENSION)" + +# this links everything into a single binary file +$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o + $(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS) + chmod a-x $(LIBRARY_NAME).$(EXTENSION) + +install: libdir_install + +# The meta and help files are explicitly installed to make sure they are +# actually there. Those files are not optional, then need to be there. +libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-examples install-manual + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + test -z "$(strip $(SOURCES))" || (\ + $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \ + $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION)))) + test -z "$(strip $(PDOBJECTS))" || \ + $(INSTALL_DATA) $(PDOBJECTS) \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + +# install library linked as single binary +single_install: $(LIBRARY_NAME) install-doc install-exec + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION) + +install-doc: + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \ + $(INSTALL_DATA) $(HELPPATCHES) \ + $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) + $(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt + $(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt + +install-examples: + test -z "$(strip $(EXAMPLES))" || \ + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \ + for file in $(EXAMPLES); do \ + $(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \ + done + +install-manual: + test -z "$(strip $(MANUAL))" || \ + $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \ + for file in $(MANUAL); do \ + $(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \ + done + + +clean: + -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o) + -rm -f -- $(SOURCES:.c=.$(EXTENSION)) + -rm -f -- $(LIBRARY_NAME).o + -rm -f -- $(LIBRARY_NAME).$(EXTENSION) + +distclean: clean + -rm -f -- $(DISTBINDIR).tar.gz + -rm -rf -- $(DISTBINDIR) + -rm -f -- $(DISTDIR).tar.gz + -rm -rf -- $(DISTDIR) + -rm -f -- $(ORIGDIR).tar.gz + -rm -rf -- $(ORIGDIR) + + +$(DISTBINDIR): + $(INSTALL_DIR) $(DISTBINDIR) + +libdir: all $(DISTBINDIR) + $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTBINDIR) + $(INSTALL_DATA) $(SOURCES) $(DISTBINDIR) + $(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR) + test -z "$(strip $(EXTRA_DIST))" || \ + $(INSTALL_DATA) $(EXTRA_DIST) $(DISTBINDIR) +# tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR) + +$(DISTDIR): + $(INSTALL_DIR) $(DISTDIR) + +$(ORIGDIR): + $(INSTALL_DIR) $(ORIGDIR) + +dist: $(DISTDIR) + $(INSTALL_DATA) Makefile $(DISTDIR) + $(INSTALL_DATA) README.txt $(DISTDIR) + $(INSTALL_DATA) LICENSE.txt $(DISTDIR) + $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTDIR) + test -z "$(strip $(ALLSOURCES))" || \ + $(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR) + test -z "$(strip $(PDOBJECTS))" || \ + $(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR) + test -z "$(strip $(HELPPATCHES))" || \ + $(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR) + test -z "$(strip $(EXTRA_DIST))" || \ + $(INSTALL_DATA) $(EXTRA_DIST) $(DISTDIR) + test -z "$(strip $(EXAMPLES))" || \ + $(INSTALL_DIR) $(DISTDIR)/examples && \ + for file in $(EXAMPLES); do \ + $(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \ + done + test -z "$(strip $(MANUAL))" || \ + $(INSTALL_DIR) $(DISTDIR)/manual && \ + for file in $(MANUAL); do \ + $(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \ + done + tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR) + +# make a Debian source package +dpkg-source: + debclean + make distclean dist + mv $(DISTDIR) $(ORIGDIR) + tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR) + rm -f -- $(DISTDIR).tar.gz + rm -rf -- $(DISTDIR) $(ORIGDIR) + cd .. && dpkg-source -b $(LIBRARY_NAME) + +etags: + etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h + +showsetup: + @echo "CFLAGS: $(CFLAGS)" + @echo "LDFLAGS: $(LDFLAGS)" + @echo "LIBS: $(LIBS)" + @echo "PD_INCLUDE: $(PD_INCLUDE)" + @echo "PD_PATH: $(PD_PATH)" + @echo "objectsdir: $(objectsdir)" + @echo "LIBRARY_NAME: $(LIBRARY_NAME)" + @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)" + @echo "SOURCES: $(SOURCES)" + @echo "PDOBJECTS: $(PDOBJECTS)" + @echo "ALLSOURCES: $(ALLSOURCES)" + @echo "UNAME: $(UNAME)" + @echo "CPU: $(CPU)" + @echo "pkglibdir: $(pkglibdir)" + @echo "DISTDIR: $(DISTDIR)" + @echo "ORIGDIR: $(ORIGDIR)" diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..f0cf42b --- /dev/null +++ b/README.txt @@ -0,0 +1,25 @@ +/* + boids package for max/msp/jitter 051219 + + Boids............................................. by eric singer + boids2d, boids3d.................................. by jasch & andr sier + jit.boids3d, jit.boids2d, xray.jit.boidsrender.... by wesley smith + + (C) 1995-98 Eric L. Singer (eric@ericsinger.com) + 3d adaptation 08/2005 by a. sier / jasch + jitter adaptation 12/2005 by w. smith + + boids package released under Gnu GPL license. + please refer to the accompanying COPYING file. +*/ + + +Based on Simon Fraser's implementation of Craig Reynolds' Boids algorithm. +Boids is free for non-commercial use + +Boids is a bird flight and animal flock simulator. It is based on the same algorithm which was used in Jurassic Park for the herding dinosaurs. +Boids takes an integer argument which is the number of boids. Each time Boids receives a bang, it calculates and outputs the new positions of the boids. The output consists of thew coordiantes for each boid, the number and type depending on the mode. + +The flight parameters can be changed with messages. Use the 'dump' message to output a list of the current parameter settings. + +For more information about the Boids algorithm, see Craig Reynolds' Web site at "http://reality.sgi.com/employees/craig/boids.html". diff --git a/boids-meta.pd b/boids-meta.pd new file mode 100644 index 0000000..4b74551 --- /dev/null +++ b/boids-meta.pd @@ -0,0 +1,9 @@ +#N canvas 10 10 200 200 10; +#N canvas 20 20 420 300 META 0; +#X text 10 10 META this is a prototype of a libdir meta file; +#X text 10 30 NAME boids; +#X text 10 50 AUTHOR Eric Singer, A. Sier, and Jasch; +#X text 10 70 DESCRIPTION 2D and 3D boids flocking algorithm; +#X text 10 90 LICENSE GNU GPL 2; +#X text 10 110 VERSION 1.1; +#X restore 10 10 pd META; diff --git a/boids.readme.txt b/boids.readme.txt deleted file mode 100644 index 8d21953..0000000 --- a/boids.readme.txt +++ /dev/null @@ -1,25 +0,0 @@ -/* - boids package for max/msp/jitter 051219 - - Boids............................................. by eric singer - boids2d, boids3d.................................. by jasch & andrŽ sier - jit.boids3d, jit.boids2d, xray.jit.boidsrender.... by wesley smith - - © 1995-98 Eric L. Singer (eric@ericsinger.com) - 3d adaptation 08/2005 by a. sier / jasch - jitter adaptation 12/2005 by w. smith - - boids package released under Gnu GPL license. - please refer to the accompanying COPYING file. -*/ - - -Based on Simon Fraser's implementation of Craig Reynolds' Boids algorithm. -Boids is free for non-commercial use - -Boids is a bird flight and animal flock simulator. It is based on the same algorithm which was used in Jurassic Park for the herding dinosaurs. -Boids takes an integer argument which is the number of boids. Each time Boids receives a bang, it calculates and outputs the new positions of the boids. The output consists of thew coordiantes for each boid, the number and type depending on the mode. - -The flight parameters can be changed with messages. Use the 'dump' message to output a list of the current parameter settings. - -For more information about the Boids algorithm, see Craig Reynolds' Web site at "http://reality.sgi.com/employees/craig/boids.html". \ No newline at end of file diff --git a/boids2d-help.pd b/boids2d-help.pd new file mode 100644 index 0000000..e48c76b --- /dev/null +++ b/boids2d-help.pd @@ -0,0 +1,732 @@ +#N canvas 0 31 975 643 10; +#X msg -99 601 dump; +#X msg 266 113 neighbors \$1; +#X floatatom 266 98 5 0 4 0 - neighbors -; +#X floatatom 266 133 5 0 0 0 - maxspeed -; +#X msg 266 148 maxspeed \$1; +#X floatatom 266 168 5 0 0 0 - minspeed -; +#X msg 266 183 minspeed \$1; +#X floatatom 266 203 5 0 0 0 - center -; +#X msg 266 218 center \$1; +#X floatatom 266 238 5 0 0 0 - attract -; +#X msg 266 253 attract \$1; +#X floatatom 266 273 5 0 0 0 - match -; +#X msg 266 288 match \$1; +#X floatatom 266 308 5 0 0 0 - avoid -; +#X msg 266 323 avoid \$1; +#X obj -125 411 r boidParam; +#X floatatom 266 343 5 0 0 0 - repel -; +#X msg 266 358 repel \$1; +#X floatatom 266 378 5 0 0 0 - edgedist -; +#X msg 266 393 edgedist \$1; +#X floatatom 266 413 5 0 0 0 - speed -; +#X msg 266 428 speed \$1; +#X floatatom 266 448 5 0 0 0 - inertia -; +#X msg 266 463 inertia \$1; +#X floatatom 266 483 5 0 0 0 - accel -; +#X msg 266 498 accel \$1; +#X floatatom 266 518 5 0 0 0 - prefdist -; +#X msg 266 533 prefdist \$1; +#X msg -99 620 reset; +#X text 357 148 maximum speed of speed range; +#X text 359 182 minimum speed of speed range; +#X text 356 217 strength of centering instinct; +#X text 358 428 overall speed; +#X text 359 499 speed of acceleration; +#X text 359 530 preferred distance from neighbors; +#X floatatom 267 556 5 0 0 0 - flyrect[0] -; +#X floatatom 306 556 5 0 0 0 - flyrect[1] -; +#X floatatom 345 556 5 0 0 0 - flyrect[2] -; +#X floatatom 384 556 5 0 0 0 - - -; +#X floatatom 266 615 5 0 0 0 - - -; +#X floatatom 306 615 5 0 0 0 - - -; +#X floatatom 266 63 5 0 0 0 - - -; +#X msg 266 78 number \$1; +#X text 357 76 number of boids; +#X floatatom -99 567 5 0 0 0 - - -; +#X msg -99 582 mode \$1; +#X text -35 582 output mode; +#X obj 266 676 s boidParam; +#X obj -99 641 s boidParam; +#X text -35 601 parameter dump; +#X text -36 621 reset boids randomly inside flyrect; +#X text 357 111 number of neighbors each boid consults when flocking +; +#X text 356 288 strength of neighbor speed matching instinct; +#X text 356 323 strength of neighbor avoidance instinct; +#X text 356 355 strength of wall avoidance instinct; +#X text 358 391 distance of vision for avoiding wall edges; +#X text 359 462 willingness to change speed and direction; +#X text 355 251 strength of attraction to 'attractpt'; +#X text -191 84 (c) 1995-98 Eric L. Singer (eric@ericsinger.com); +#X text -191 126 Based on Simon Fraser's implementation of Craig Reynolds' +Boids algorithm. Boids is free for non-commercial use; +#X text -191 159 Boids is a bird flight and animal flock simulator. +It is based on the same algorithm which was used in Jurassic Park for +the herding dinosaurs.; +#X text -191 208 Boids takes an integer argument which is the number +of boids. Each time Boids receives a bang \, it calculates and outputs +the new positions of the boids. The output consists of thew coordiantes +for each boid \, the number and type depending on the mode.; +#X text -190 282 The flight parameters can be changed with messages. +Use the 'dump' message to output a list of the current parameter settings. +; +#X text -190 328 For more information about the Boids algorithm \, +see Craig Reynolds' Web site at "http://reality.sgi.com/employees/craig/boids.html". +; +#X text -188 64 arguments: number of boids \, output +mode; +#X obj -72 460 print dump; +#X obj -203 9 cnv 15 800 48 empty empty boids2d 20 12 2 24 -228915 +-66577 0; +#X obj -151 410 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 +-1 -1; +#N canvas 430 22 471 383 gem_example 0; +#X msg 33 31 destroy; +#N canvas 494 140 629 324 gemwin 0; +#X obj 219 190 gemwin; +#X obj 66 194 outlet; +#X obj 67 10 inlet; +#X obj 67 41 route create; +#X msg 67 70 set destroy; +#X msg 157 70 set create; +#X msg 350 115 destroy \, reset; +#X msg 238 71 color 0 0 0.5; +#X msg 212 146 create \, 1 \, frame 30 \, color 1 1 1; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 3 0 8 0; +#X connect 3 1 5 0; +#X connect 3 1 6 0; +#X connect 4 0 1 0; +#X connect 5 0 1 0; +#X connect 6 0 0 0; +#X connect 7 0 0 0; +#X connect 8 0 0 0; +#X restore 33 51 pd gemwin; +#X obj 33 91 tgl 15 0 empty empty start_flocking_animation 20 6 1 10 +-262144 -1 -1 0 1; +#X obj 204 135 r boidParam; +#X obj 33 112 metro 33; +#X floatatom 33 244 5 0 0 0 - - -; +#X floatatom 84 244 5 0 0 0 - - -; +#X obj 86 318 s boidParam; +#N canvas 0 22 466 316 orbit 0; +#X obj 103 82 counter 360; +#X floatatom 103 107 5 0 0 0 - - -; +#X obj 102 204 poltocar; +#X obj 134 169 expr $f1 * (3.141593/180.); +#X obj 103 134 t b f; +#X obj 103 45 inlet; +#X obj 152 254 outlet; +#X obj 96 254 outlet; +#X obj 102 170 1.5; +#X connect 0 0 1 0; +#X connect 1 0 4 0; +#X connect 2 0 6 0; +#X connect 2 1 7 0; +#X connect 3 0 2 1; +#X connect 4 0 8 0; +#X connect 4 1 3 0; +#X connect 5 0 0 0; +#X connect 8 0 2 0; +#X restore 33 222 pd orbit; +#X text 96 30 create/destroy OpenGl context; +#X obj 33 181 spigot; +#X obj 69 160 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 339 113 s init; +#X obj 358 84 loadbang; +#X obj 340 85 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#N canvas 0 22 418 379 center 0; +#X obj 101 37 gemhead; +#X obj 99 201 translateXYZ; +#X obj 124 166 unpack 0 0 0; +#X obj 147 94 inlet; +#X msg 240 193 draw line; +#X obj 252 106 loadbang; +#X obj 100 131 alpha; +#X obj 101 68 color 1 0.5 0 0.5; +#X obj 99 228 circle 0.1; +#X connect 0 0 7 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 8 0; +#X connect 5 0 4 0; +#X connect 6 0 1 0; +#X connect 7 0 6 0; +#X restore 32 342 pd center; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 205 224 pd boid; +#X msg 85 295 attractpt \$1 \$2; +#X obj 33 267 pack 0 0; +#X obj 205 163 boids2d 10; +#X obj 206 191 route 0 1 2 3 4 5 6 7 8 9; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 215 234 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 225 244 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 235 254 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 245 264 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 255 274 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 265 284 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 275 294 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 285 304 pd boid; +#N canvas 213 30 518 368 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X obj 192 162 unpack 0 0; +#X connect 0 0 4 0; +#X connect 1 0 7 0; +#X connect 2 0 8 0; +#X connect 3 0 1 0; +#X connect 4 0 3 0; +#X connect 5 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 3 1; +#X connect 8 0 1 1; +#X connect 8 1 1 2; +#X restore 295 314 pd boid; +#X connect 0 0 1 0; +#X connect 1 0 0 0; +#X connect 2 0 4 0; +#X connect 3 0 19 0; +#X connect 4 0 10 0; +#X connect 4 0 19 0; +#X connect 5 0 18 0; +#X connect 6 0 18 1; +#X connect 8 0 5 0; +#X connect 8 1 6 0; +#X connect 10 0 8 0; +#X connect 11 0 10 1; +#X connect 13 0 12 0; +#X connect 13 0 11 0; +#X connect 14 0 12 0; +#X connect 17 0 7 0; +#X connect 18 0 17 0; +#X connect 18 0 15 0; +#X connect 19 0 20 0; +#X connect 20 0 16 0; +#X connect 20 1 21 0; +#X connect 20 2 22 0; +#X connect 20 3 23 0; +#X connect 20 4 24 0; +#X connect 20 5 25 0; +#X connect 20 6 26 0; +#X connect 20 7 27 0; +#X connect 20 8 28 0; +#X connect 20 9 29 0; +#X restore 57 430 pd gem_example; +#X obj 266 574 pack 0 0 0 0 0 0; +#X obj 266 632 pack 0 0 0; +#X floatatom 345 615 5 0 0 0 - - -; +#X text -190 105 float/2d/3d adaptation 08/2005 by a. sier / jasch +; +#N canvas 754 114 186 470 init 0; +#X obj 34 21 loadbang; +#X obj 94 21 r reset; +#X msg 15 78 \; neighbors 4; +#X msg 15 348 \; speed 3; +#X obj 16 49 b; +#X obj 17 21 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 15 438 \; prefdist 1.5; +#X msg 15 108 \; maxspeed 1.5; +#X msg 15 138 \; minspeed 1.2; +#X msg 15 168 \; center 1.2; +#X msg 15 198 \; attract 1.25; +#X msg 15 228 \; match 0.3; +#X msg 15 288 \; repel 3.5; +#X msg 15 258 \; avoid 3.5; +#X msg 15 318 \; edgedist 3; +#X msg 15 379 \; inertia 4.5; +#X msg 15 408 \; accel 2.5; +#X connect 0 0 4 0; +#X connect 1 0 4 0; +#X connect 4 0 2 0; +#X connect 4 0 7 0; +#X connect 4 0 8 0; +#X connect 4 0 9 0; +#X connect 4 0 10 0; +#X connect 4 0 11 0; +#X connect 4 0 13 0; +#X connect 4 0 12 0; +#X connect 4 0 3 0; +#X connect 4 0 15 0; +#X connect 4 0 16 0; +#X connect 4 0 6 0; +#X connect 5 0 4 0; +#X restore 57 411 pd init; +#X obj -151 438 boids2d 16 0; +#X obj -150 488 print boids2d; +#X msg 266 592 flyrect \$1 \$2 \$3 \$4; +#X msg 266 652 attractpt \$1 \$2; +#X text 389 614 point to which boids are attracted (x/y); +#X text 392 575 bounding box (walls) in which to fly (l/t/r/b); +#N canvas 88 105 494 344 META 0; +#X text 12 165 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan +Wilkes for Pd version 0.42.; +#X text 12 145 AUTHOR Eric L. Singer; +#X text 12 5 KEYWORDS control; +#X text 12 45 DESCRIPTION bird flight and animal flock simulator; +#X text 12 65 INLET_0 bang dump mode reset number neighbors maxspeed +minspeed center attract match avoid repel edgedist speed inertia accel +prefdist flyrect attractpt; +#X text 12 105 OUTLET_0 list; +#X text 12 125 OUTLET_1 list; +#X text 12 25 LICENSE GPL v2; +#X restore 720 676 pd META; +#X connect 0 0 48 0; +#X connect 1 0 47 0; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 47 0; +#X connect 5 0 6 0; +#X connect 6 0 47 0; +#X connect 7 0 8 0; +#X connect 8 0 47 0; +#X connect 9 0 10 0; +#X connect 10 0 47 0; +#X connect 11 0 12 0; +#X connect 12 0 47 0; +#X connect 13 0 14 0; +#X connect 14 0 47 0; +#X connect 15 0 74 0; +#X connect 16 0 17 0; +#X connect 17 0 47 0; +#X connect 18 0 19 0; +#X connect 19 0 47 0; +#X connect 20 0 21 0; +#X connect 21 0 47 0; +#X connect 22 0 23 0; +#X connect 23 0 47 0; +#X connect 24 0 25 0; +#X connect 25 0 47 0; +#X connect 26 0 27 0; +#X connect 27 0 47 0; +#X connect 28 0 48 0; +#X connect 35 0 69 0; +#X connect 36 0 69 1; +#X connect 37 0 69 2; +#X connect 38 0 69 3; +#X connect 39 0 70 0; +#X connect 40 0 70 1; +#X connect 41 0 42 0; +#X connect 42 0 47 0; +#X connect 44 0 45 0; +#X connect 45 0 48 0; +#X connect 67 0 74 0; +#X connect 69 0 76 0; +#X connect 70 0 77 0; +#X connect 71 0 70 2; +#X connect 74 0 75 0; +#X connect 74 1 65 0; +#X connect 76 0 47 0; +#X connect 77 0 47 0; diff --git a/boids2d.c b/boids2d.c new file mode 100644 index 0000000..520a3ae --- /dev/null +++ b/boids2d.c @@ -0,0 +1,962 @@ +/* + + boids2d 08/2005 a.sier / jasch adapted from boids by eric singer 1995-2003 eric l. singer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "m_pd.h" +#include +#include + +// constants +#define kAssistInlet 1 +#define kAssistOutlet 2 +#define kMaxLong 0xFFFFFFFF +#define kMaxNeighbors 4 + +// util +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define CLIP(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x) + +// initial flight parameters +const short kNumBoids = 12; // number of boids +const short kNumNeighbors = 2; // must be <= kMaxNeighbors +const double kMinSpeed = 0.15; // boids' minimum speed +const double kMaxSpeed = 0.25; // boids' maximum speed +const double kCenterWeight = 0.25; // flock centering +const double kAttractWeight = 0.300;// attraction point seeking +const double kMatchWeight = 0.100;// neighbors velocity matching +const double kAvoidWeight = 0.10; // neighbors avoidance +const double kWallsWeight = 0.500;// wall avoidance [210] +const double kEdgeDist = 0.5; // vision distance to avoid wall edges [5] +const double kSpeedupFactor = 0.100;// alter animation speed +const double kInertiaFactor = 0.20; // willingness to change speed & direction +const double kAccelFactor = 0.100;// neighbor avoidance accelerate or decelerate rate +const double kPrefDist = 0.25; // preferred distance from neighbors +const double kFlyRectTop = 1.0; // fly rect boundaries +const double kFlyRectLeft = -1.0; +const double kFlyRectBottom = -1.0; +const double kFlyRectRight = 1.0; +// const double kFlyRectFront = 1.0; +// const double kFlyRectBack = -1.0; + + +// typedefs +typedef struct Velocity { + double x; + double y; +// double z; +} Velocity; + +typedef struct Point2d { + double x; + double y; +// double z; +} Point2d; + +typedef struct Box3D { + double left, right; + double top, bottom; +// double front, back; +} Box3D; + +typedef struct _Boid { + Point2d oldPos; + Point2d newPos; + Velocity oldDir; + Velocity newDir; + double speed; + short neighbor[kMaxNeighbors]; + double neighborDistSqr[kMaxNeighbors]; +} t_one_boid, *BoidPtr; + +typedef struct _FlockObject { + t_object ob; + void *out1, *out2; + short mode; + long numBoids; + long numNeighbors; + Box3D flyRect; + double minSpeed; + double maxSpeed; + double centerWeight; + double attractWeight; + double matchWeight; + double avoidWeight; + double wallsWeight; + double edgeDist; + double speedupFactor; + double inertiaFactor; + double accelFactor; + double prefDist; + double prefDistSqr; + Point2d centerPt; + Point2d attractPt; + BoidPtr boid; + double d2r, r2d; +} t_boids, *FlockPtr; + +// variables +// void *flock; +t_symbol *ps_nothing; + +// prototypes +void *boids2d_class; +void *Flock_new(t_symbol *s, long argc, t_atom *argv); +void Flock_free(t_boids *x); +void Flock_bang(t_boids *x); +void Flock_dump(t_boids *x); +void Flock_mode(t_boids *x, t_float arg); +void Flock_numNeighbors(t_boids *x, t_float arg); +void Flock_numBoids(t_boids *x, t_float arg); +void Flock_minSpeed(t_boids *x, t_float arg); +void Flock_maxSpeed(t_boids *x, t_float arg); +void Flock_centerWeight(t_boids *x, t_float arg); +void Flock_attractWeight(t_boids *x, t_float arg); +void Flock_matchWeight(t_boids *x, t_float arg); +void Flock_avoidWeight(t_boids *x, t_float arg); +void Flock_wallsWeight(t_boids *x, t_float arg); +void Flock_edgeDist(t_boids *x, t_float arg); +void Flock_speedupFactor(t_boids *x, t_float arg); +void Flock_inertiaFactor(t_boids *x, t_float arg); +void Flock_accelFactor(t_boids *x, t_float arg); +void Flock_prefDist(t_boids *x, t_float arg); +void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv); +void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv); +void Flock_reset(t_boids *x); +void Flock_resetBoids(t_boids *x); +void InitFlock(t_boids *x); +void FlightStep(t_boids *x); +Point2d FindFlockCenter(t_boids *x); +float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel); +Velocity SeekPoint(t_boids *x, short theBoid, Point2d seekPt); +Velocity AvoidWalls(t_boids *x, short theBoid); +int InFront(BoidPtr theBoid, BoidPtr neighbor); +void NormalizeVelocity(Velocity *direction); +double RandomInt(double minRange, double maxRange); +double DistSqrToPt(Point2d firstPoint, Point2d secondPoint); + +void boids2d_setup(void) +{ + boids2d_class = class_new(gensym("boids2d"), (t_newmethod)Flock_new, + (t_method)Flock_free, sizeof(t_boids), 0, A_GIMME, 0); + /* setup((t_messlist **) &flock, (method)Flock_new, (method)Flock_free, (short) sizeof(FlockObject), 0L, A_LONG, A_DEFLONG, 0); */ + class_addfloat(boids2d_class, (t_method) Flock_numBoids); + class_addbang(boids2d_class, (t_method) Flock_bang); + class_addmethod(boids2d_class, (t_method) Flock_numNeighbors, gensym("neighbors"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_numBoids, gensym("number"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_mode, gensym("mode"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_minSpeed, gensym("minspeed"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_maxSpeed, gensym("maxspeed"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_centerWeight, gensym("center"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_attractWeight, gensym("attract"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_matchWeight, gensym("match"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_avoidWeight, gensym("avoid"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_wallsWeight, gensym("repel"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_edgeDist, gensym("edgedist"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_speedupFactor, gensym("speed"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_inertiaFactor, gensym("inertia"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_accelFactor, gensym("accel"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_prefDist, gensym("prefdist"), A_FLOAT, 0); + class_addmethod(boids2d_class, (t_method) Flock_flyRect, gensym("flyrect"), A_GIMME, 0); + class_addmethod(boids2d_class, (t_method) Flock_attractPt, gensym("attractpt"), A_GIMME, 0); + class_addmethod(boids2d_class, (t_method) Flock_resetBoids, gensym("reset"), 0); + class_addmethod(boids2d_class, (t_method) Flock_reset, gensym("init"), 0); + class_addmethod(boids2d_class, (t_method) Flock_dump, gensym("dump"), 0); + + post("boids2d 2005-2006 a.sier / jasch 1995-2003 eric l. singer "__DATE__" "__TIME__); + ps_nothing = gensym(""); +} + + +void *Flock_new(t_symbol *s, long argc, t_atom *argv) +{ + t_boids *x = (t_boids *)pd_new(boids2d_class); + x->out1 = outlet_new(&x->ob, NULL); + x->out2 = outlet_new(&x->ob, NULL); + + x->numBoids = 16; + if((argc >= 1) && (argv[0].a_type == A_FLOAT)){ + x->numBoids = argv[0].a_w.w_float; + } + x->boid = (t_one_boid *)malloc(sizeof(t_one_boid) * x->numBoids); + + InitFlock(x); + + x->mode = 0; + if((argc >= 2) && (argv[1].a_type == A_FLOAT)){ + x->mode = (short)(CLIP(argv[1].a_w.w_float, 0, 2)); + } + + x->d2r = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068/180.0; + x->r2d = 180.0/3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068; + + return(x); +} + + +void Flock_free(t_boids *x) +{ + free(x->boid); +} + +void Flock_bang(t_boids *x) +{ + short i; + t_atom outlist[10]; + t_atom *out; + + double tempNew_x, tempNew_y; + double tempOld_x, tempOld_y; + double delta_x, delta_y; + double azi, speed; + // double tempspeed; + + out = outlist; + + FlightStep(x); + + + switch(x->mode) { // newpos + case 0: + for (i = 0; i < x->numBoids; i++){ + SETFLOAT(out+0, i); + SETFLOAT(out+1, x->boid[i].newPos.x); + SETFLOAT(out+2, x->boid[i].newPos.y); + // SETFLOAT(out+3, x->boid[i].newPos.z); + outlet_list(x->out1, 0L, 3, out); + } + break; + case 1: //newpos + oldpos + for (i = 0; i < x->numBoids; i++){ + SETFLOAT(out+0, i); + SETFLOAT(out+1, x->boid[i].newPos.x); + SETFLOAT(out+2, x->boid[i].newPos.y); + // SETFLOAT(out+3, x->boid[i].newPos.z); + SETFLOAT(out+3, x->boid[i].oldPos.x); + SETFLOAT(out+4, x->boid[i].oldPos.y); + // SETFLOAT(out+6, x->boid[i].oldPos.z); + outlet_list(x->out1, 0L, 5, out); + } + break; + case 2: + for (i = 0; i < x->numBoids; i++){ + tempNew_x = x->boid[i].newPos.x; + tempNew_y = x->boid[i].newPos.y; + // tempNew_z = x->boid[i].newPos.z; + tempOld_x = x->boid[i].oldPos.x; + tempOld_y = x->boid[i].oldPos.y; + // tempOld_z = x->boid[i].oldPos.z; + delta_x = tempNew_x - tempOld_x; + delta_y = tempNew_y - tempOld_y; + // delta_z = tempNew_z - tempOld_z; + azi = atan2(delta_y, delta_x) * x->r2d; + // ele = atan2(delta_y, delta_x) * x->r2d; + speed = sqrt(delta_x * delta_x + delta_y * delta_y);// + delta_z * delta_z); + SETFLOAT(out+0, i); + SETFLOAT(out+1, tempNew_x); + SETFLOAT(out+2, tempNew_y); + // SETFLOAT(out+3, tempNew_z); + SETFLOAT(out+3, tempOld_x); + SETFLOAT(out+4, tempOld_y); + // SETFLOAT(out+6, tempOld_z); + SETFLOAT(out+5, speed); + SETFLOAT(out+6, azi); + // SETFLOAT(out+9, ele); + outlet_list(x->out1, 0L, 7, out); + } + break; + } +} + +void Flock_dump(t_boids *x) +{ + t_atom outList[6]; + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->numNeighbors; + outlet_anything(x->out2, gensym("neighbors"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->minSpeed; + outlet_anything(x->out2, gensym("minspeed"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->maxSpeed; + outlet_anything(x->out2, gensym("maxspeed"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->centerWeight; + outlet_anything(x->out2, gensym("center"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->attractWeight; + outlet_anything(x->out2, gensym("attract"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->matchWeight; + outlet_anything(x->out2, gensym("match"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->avoidWeight; + outlet_anything(x->out2, gensym("avoid"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->wallsWeight; + outlet_anything(x->out2, gensym("repel"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->edgeDist; + outlet_anything(x->out2, gensym("edgedist"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->speedupFactor; + outlet_anything(x->out2, gensym("speed"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->inertiaFactor; + outlet_anything(x->out2, gensym("inertia"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->accelFactor; + outlet_anything(x->out2, gensym("accel"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->prefDist; + outlet_anything(x->out2, gensym("prefdist"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->flyRect.left; + outList[1].a_type = A_FLOAT; + outList[1].a_w.w_float = x->flyRect.top; + outList[2].a_type = A_FLOAT; + outList[2].a_w.w_float = x->flyRect.right; + outList[3].a_type = A_FLOAT; + outList[3].a_w.w_float = x->flyRect.bottom; + /*outList[4].a_type = A_FLOAT; + outList[4].a_w.w_float = x->flyRect.front; + outList[5].a_type = A_FLOAT; + outList[5].a_w.w_float = x->flyRect.back;*/ + outlet_anything(x->out2, gensym("flyrect"), 4, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->attractPt.x; + outList[1].a_type = A_FLOAT; + outList[1].a_w.w_float = x->attractPt.y; + /*outList[2].a_type = A_FLOAT; + outList[2].a_w.w_float = x->attractPt.z;*/ + outlet_anything(x->out2, gensym("attractpt"), 2, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->mode; + outlet_anything(x->out2, gensym("mode"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->numBoids; + outlet_anything(x->out2, gensym("number"), 1, outList); +} + + +void Flock_mode(t_boids *x, t_float arg) +{ + long m = (long)arg; + x->mode = CLIP(m, 0, 2); +} + +void Flock_numNeighbors(t_boids *x, t_float arg) +{ + x->numNeighbors = (long)arg; +} + +void Flock_numBoids(t_boids *x, t_float arg) +{ + x->boid = (t_one_boid *)realloc(x->boid, sizeof(t_one_boid) * (long)arg); + x->numBoids = (long)arg; + Flock_resetBoids(x); +} + +void Flock_minSpeed(t_boids *x, t_float arg) +{ + x->minSpeed = MAX(arg, 0.000001); +} + +void Flock_maxSpeed(t_boids *x, t_float arg) +{ + x->maxSpeed = (double)arg; +} + +void Flock_centerWeight(t_boids *x, t_float arg) +{ + x->centerWeight = (double)arg; +} + +void Flock_attractWeight(t_boids *x, t_float arg) +{ + x->attractWeight = (double)arg; +} + +void Flock_matchWeight(t_boids *x, t_float arg) +{ + x->matchWeight = (double)arg; +} + +void Flock_avoidWeight(t_boids *x, t_float arg) +{ + x->avoidWeight = (double)arg; +} + +void Flock_wallsWeight(t_boids *x, t_float arg) +{ + x->wallsWeight = (double)arg; +} + +void Flock_edgeDist(t_boids *x, t_float arg) +{ + x->edgeDist = (double)arg; +} + +void Flock_speedupFactor(t_boids *x, t_float arg) +{ + x->speedupFactor = (double)arg; +} + +void Flock_inertiaFactor(t_boids *x, t_float arg) +{ + if(arg == 0){ + x->inertiaFactor = 0.000001; + }else{ + x->inertiaFactor = (double)arg; + } +} + +void Flock_accelFactor(t_boids *x, t_float arg) +{ + x->accelFactor = (double)arg; +} + +void Flock_prefDist(t_boids *x, t_float arg) +{ + x->prefDist = (double)arg; +} + +void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv) +{ + double temp[4]; + short i; + if(argc == 4){ + for(i=0;i<4;i++) { + if(argv[i].a_type == A_FLOAT) { + temp[i] = (double)argv[i].a_w.w_float; + } + } + x->flyRect.left = temp[0]; + x->flyRect.top = temp[1]; + x->flyRect.right = temp[2]; + x->flyRect.bottom = temp[3]; + // x->flyRect.front = temp[4]; + // x->flyRect.back = temp[5]; + }else{ + error("boids2d: flyrect needs four values"); + } +} + +void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv) +{ + double temp[2]; + short i; + if(argc == 2){ + for(i=0;i<2;i++) { + if(argv[i].a_type == A_FLOAT) { + temp[i] = (double)argv[i].a_w.w_float; + } + } + x->attractPt.x = temp[0]; + x->attractPt.y = temp[1]; + // x->attractPt.z = temp[2]; + }else{ + error("boids2d: attractPt needs two values"); + } +} + +void Flock_reset(t_boids *x) +{ + InitFlock(x); +} + +void Flock_resetBoids(t_boids *x) +{ + long i, j; + double rndAngle; + + for (i = 0; i < x->numBoids; i++) { // init everything to 0.0 + x->boid[i].oldPos.x = 0.0; + x->boid[i].oldPos.y = 0.0; + // x->boid[i].oldPos.z = 0.0; + + x->boid[i].newPos.x = 0.0; + x->boid[i].newPos.y = 0.0; + // x->boid[i].newPos.z = 0.0; + + x->boid[i].oldDir.x = 0.0; + x->boid[i].oldDir.y = 0.0; + // x->boid[i].oldDir.z = 0.0; + + x->boid[i].newDir.x = 0.0; + x->boid[i].newDir.y = 0.0; + // x->boid[i].newDir.z = 0.0; + + x->boid[i].speed = 0.0; + + for(j=0; jboid[i].neighbor[j] = 0; + x->boid[i].neighborDistSqr[j] = 0.0; + } + } + for (i = 0; i < x->numBoids; i++) { // set the initial locations and velocities of the boids + x->boid[i].newPos.x = x->boid[i].oldPos.x = RandomInt(x->flyRect.right,x->flyRect.left); // set random location within flyRect + x->boid[i].newPos.y = x->boid[i].oldPos.y = RandomInt(x->flyRect.bottom, x->flyRect.top); + // x->boid[i].newPos.z = x->boid[i].oldPos.z = RandomInt(x->flyRect.back, x->flyRect.front); + rndAngle = RandomInt(0, 360) * x->d2r; // set velocity from random angle + x->boid[i].newDir.x = sin(rndAngle); + x->boid[i].newDir.y = cos(rndAngle); + // x->boid[i].newDir.z = (cos(rndAngle) + sin(rndAngle)) * 0.5; + x->boid[i].speed = (kMaxSpeed + kMinSpeed) * 0.5; + } +} + +void InitFlock(t_boids *x) +{ + x->numNeighbors = kNumNeighbors; + x->minSpeed = kMinSpeed; + x->maxSpeed = kMaxSpeed; + x->centerWeight = kCenterWeight; + x->attractWeight = kAttractWeight; + x->matchWeight = kMatchWeight; + x->avoidWeight = kAvoidWeight; + x->wallsWeight = kWallsWeight; + x->edgeDist = kEdgeDist; + x->speedupFactor = kSpeedupFactor; + x->inertiaFactor = kInertiaFactor; + x->accelFactor = kAccelFactor; + x->prefDist = kPrefDist; + x->prefDistSqr = kPrefDist * kPrefDist; + x->flyRect.top = kFlyRectTop; + x->flyRect.left = kFlyRectLeft; + x->flyRect.bottom = kFlyRectBottom; + x->flyRect.right = kFlyRectRight; + // x->flyRect.front = kFlyRectFront; + // x->flyRect.back = kFlyRectBack; + x->attractPt.x = (kFlyRectLeft + kFlyRectRight) * 0.5; + x->attractPt.y = (kFlyRectTop + kFlyRectBottom) * 0.5; + // x->attractPt.z = (kFlyRectFront + kFlyRectBack) * 0.5; + Flock_resetBoids(x); +} + +void FlightStep(t_boids *x) +{ + Velocity goCenterVel; + Velocity goAttractVel; + Velocity matchNeighborVel; + Velocity avoidWallsVel; + Velocity avoidNeighborVel; + float avoidNeighborSpeed; + const Velocity zeroVel = {0.0, 0.0};//, 0.0}; + short i; + + x->centerPt = FindFlockCenter(x); + for (i = 0; i < x->numBoids; i++) { // save position and velocity + x->boid[i].oldPos.x = x->boid[i].newPos.x; + x->boid[i].oldPos.y = x->boid[i].newPos.y; + // x->boid[i].oldPos.z = x->boid[i].newPos.z; + + x->boid[i].oldDir.x = x->boid[i].newDir.x; + x->boid[i].oldDir.y = x->boid[i].newDir.y; + // x->boid[i].oldDir.z = x->boid[i].newDir.z; + } + for (i = 0; i < x->numBoids; i++) { + if (x->numNeighbors > 0) { // get all velocity components + avoidNeighborSpeed = MatchAndAvoidNeighbors(x, i,&matchNeighborVel, &avoidNeighborVel); + } else { + matchNeighborVel = zeroVel; + avoidNeighborVel = zeroVel; + avoidNeighborSpeed = 0; + } + goCenterVel = SeekPoint(x, i, x->centerPt); + goAttractVel = SeekPoint(x, i, x->attractPt); + avoidWallsVel = AvoidWalls(x, i); + + // compute resultant velocity using weights and inertia + x->boid[i].newDir.x = x->inertiaFactor * (x->boid[i].oldDir.x) + + (x->centerWeight * goCenterVel.x + + x->attractWeight * goAttractVel.x + + x->matchWeight * matchNeighborVel.x + + x->avoidWeight * avoidNeighborVel.x + + x->wallsWeight * avoidWallsVel.x) / x->inertiaFactor; + x->boid[i].newDir.y = x->inertiaFactor * (x->boid[i].oldDir.y) + + (x->centerWeight * goCenterVel.y + + x->attractWeight * goAttractVel.y + + x->matchWeight * matchNeighborVel.y + + x->avoidWeight * avoidNeighborVel.y + + x->wallsWeight * avoidWallsVel.y) / x->inertiaFactor; + /*x->boid[i].newDir.z = x->inertiaFactor * (x->boid[i].oldDir.z) + + (x->centerWeight * goCenterVel.z + + x->attractWeight * goAttractVel.z + + x->matchWeight * matchNeighborVel.z + + x->avoidWeight * avoidNeighborVel.z + + x->wallsWeight * avoidWallsVel.z) / x->inertiaFactor;*/ + NormalizeVelocity(&(x->boid[i].newDir)); // normalize velocity so its length is unity + + // set to avoidNeighborSpeed bounded by minSpeed and maxSpeed + if ((avoidNeighborSpeed >= x->minSpeed) && + (avoidNeighborSpeed <= x->maxSpeed)) + x->boid[i].speed = avoidNeighborSpeed; + else if (avoidNeighborSpeed > x->maxSpeed) + x->boid[i].speed = x->maxSpeed; + else + x->boid[i].speed = x->minSpeed; + + // calculate new position, applying speedupFactor + x->boid[i].newPos.x += x->boid[i].newDir.x * x->boid[i].speed * (x->speedupFactor / 100.0); + x->boid[i].newPos.y += x->boid[i].newDir.y * x->boid[i].speed * (x->speedupFactor / 100.0); + // x->boid[i].newPos.z += x->boid[i].newDir.z * x->boid[i].speed * (x->speedupFactor / 100.0); + + } +} + +Point2d FindFlockCenter(t_boids *x) +{ + double totalH = 0, totalV = 0, totalD = 0; + Point2d centerPoint; + short i; + + for (i = 0 ; i < x->numBoids; i++) + { + totalH += x->boid[i].oldPos.x; + totalV += x->boid[i].oldPos.y; + // totalD += x->boid[i].oldPos.z; + } + centerPoint.x = (double)(totalH / x->numBoids); + centerPoint.y = (double)(totalV / x->numBoids); + // centerPoint.z = (double) (totalD / x->numBoids); + + return(centerPoint); +} + +float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel) +{ + short i, j, neighbor; + double distSqr; + double dist, distH, distV,distD; + double tempSpeed; + short numClose = 0; + Velocity totalVel = {0.0,0.0};//,0.0}; + + /**********************/ + /* Find the neighbors */ + /**********************/ + + /* special case of one neighbor */ + if (x->numNeighbors == 1) { + x->boid[theBoid].neighborDistSqr[0] = kMaxLong; + + for (i = 0; i < x->numBoids; i++) { + if (i != theBoid) { + distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); + + /* if this one is closer than the closest so far, then remember it */ + if (x->boid[theBoid].neighborDistSqr[0] > distSqr) { + x->boid[theBoid].neighborDistSqr[0] = distSqr; + x->boid[theBoid].neighbor[0] = i; + } + } + } + } + /* more than one neighbor */ + else { + for (j = 0; j < x->numNeighbors; j++) + x->boid[theBoid].neighborDistSqr[j] = kMaxLong; + + for (i = 0 ; i < x->numBoids; i++) { + /* if this one is not me... */ + if (i != theBoid) { + distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); + + /* if distSqr is less than the distance at the bottom of the array, sort into array */ + if (distSqr < x->boid[theBoid].neighborDistSqr[x->numNeighbors-1]) { + j = x->numNeighbors - 1; + + /* sort distSqr in to keep array in size order, smallest first */ + while ((distSqr < x->boid[theBoid].neighborDistSqr[j-1]) && (j > 0)) { + x->boid[theBoid].neighborDistSqr[j] = x->boid[theBoid].neighborDistSqr[j - 1]; + x->boid[theBoid].neighbor[j] = x->boid[theBoid].neighbor[j - 1]; + j--; + } + x->boid[theBoid].neighborDistSqr[j] = distSqr; + x->boid[theBoid].neighbor[j] = i; + } + } + } + } + + /*********************************/ + /* Match and avoid the neighbors */ + /*********************************/ + + matchNeighborVel->x = 0; + matchNeighborVel->y = 0; + // matchNeighborVel->z = 0; + + // set tempSpeed to old speed + tempSpeed = x->boid[theBoid].speed; + + for (i = 0; i < x->numNeighbors; i++) { + neighbor = x->boid[theBoid].neighbor[i]; + + // calculate matchNeighborVel by averaging the neighbor velocities + matchNeighborVel->x += x->boid[neighbor].oldDir.x; + matchNeighborVel->y += x->boid[neighbor].oldDir.y; + // matchNeighborVel->z += x->boid[neighbor].oldDir.z; + + // if distance is less than preferred distance, then neighbor influences boid + distSqr = x->boid[theBoid].neighborDistSqr[i]; + if (distSqr < x->prefDistSqr) { + dist = sqrt(distSqr); + + distH = x->boid[neighbor].oldPos.x - x->boid[theBoid].oldPos.x; + distV = x->boid[neighbor].oldPos.y - x->boid[theBoid].oldPos.y; + // distD = x->boid[neighbor].oldPos.z - x->boid[theBoid].oldPos.z; + + if(dist == 0.0) dist = 0.0000001; + totalVel.x = totalVel.x - distH - (distH * ((float) x->prefDist / (dist))); + totalVel.y = totalVel.y - distV - (distV * ((float) x->prefDist / (dist))); + // totalVel.z = totalVel.z - distD - (distV * ((float) x->prefDist / (dist))); + + numClose++; + } + if (InFront(&(x->boid[theBoid]), &(x->boid[neighbor]))) { // adjust speed + if (distSqr < x->prefDistSqr) + tempSpeed /= (x->accelFactor / 100.0); + else + tempSpeed *= (x->accelFactor / 100.0); + } + else { + if (distSqr < x->prefDistSqr) + tempSpeed *= (x->accelFactor / 100.0); + else + tempSpeed /= (x->accelFactor / 100.0); + } + } + if (numClose) { + avoidNeighborVel->x = totalVel.x / numClose; + avoidNeighborVel->y = totalVel.y / numClose; + // avoidNeighborVel->z = totalVel.z / numClose; + NormalizeVelocity(matchNeighborVel); + } + else { + avoidNeighborVel->x = 0; + avoidNeighborVel->y = 0; + // avoidNeighborVel->z = 0; + } + return(tempSpeed); +} + + +Velocity SeekPoint(t_boids *x, short theBoid, Point2d seekPt) +{ + Velocity tempDir; + tempDir.x = seekPt.x - x->boid[theBoid].oldPos.x; + tempDir.y = seekPt.y - x->boid[theBoid].oldPos.y; + // tempDir.z = seekPt.z - x->boid[theBoid].oldPos.z; + NormalizeVelocity(&tempDir); + return(tempDir); +} + + +Velocity AvoidWalls(t_boids *x, short theBoid) +{ + Point2d testPoint; + Velocity tempVel = {0.0, 0.0};//, 0.0}; + + /* calculate test point in front of the nose of the boid */ + /* distance depends on the boid's speed and the avoid edge constant */ + testPoint.x = x->boid[theBoid].oldPos.x + x->boid[theBoid].oldDir.x * x->boid[theBoid].speed * x->edgeDist; + testPoint.y = x->boid[theBoid].oldPos.y + x->boid[theBoid].oldDir.y * x->boid[theBoid].speed * x->edgeDist; + // testPoint.z = x->boid[theBoid].oldPos.z + x->boid[theBoid].oldDir.z * x->boid[theBoid].speed * x->edgeDist; + + /* if test point is out of the left (right) side of x->flyRect, */ + /* return a positive (negative) horizontal velocity component */ + if (testPoint.x < x->flyRect.left) + tempVel.x = fabs(x->boid[theBoid].oldDir.x); + else if (testPoint.x > x->flyRect.right) + tempVel.x = - fabs(x->boid[theBoid].oldDir.x); + + /* same with top and bottom */ + if (testPoint.y < x->flyRect.top) + tempVel.y = fabs(x->boid[theBoid].oldDir.y); + else if (testPoint.y > x->flyRect.bottom) + tempVel.y = - fabs(x->boid[theBoid].oldDir.y); + + /* same with front and back + if (testPoint.z < x->flyRect.front) + tempVel.z = fabs(x->boid[theBoid].oldDir.z); + else if (testPoint.z > x->flyRect.back) + tempVel.z = - fabs(x->boid[theBoid].oldDir.z); + */ + + return(tempVel); +} + + +int InFront(BoidPtr theBoid, BoidPtr neighbor) +{ + float grad, intercept; + int result; + +/* + +Find the gradient and y-intercept of a line passing through theBoid's oldPos +perpendicular to its direction of motion. Another boid is in front of theBoid +if it is to the right or left of this linedepending on whether theBoid is moving +right or left. However, if theBoid is travelling vertically then just compare +their vertical coordinates. + +*/ + // xy plane + + // if theBoid is not travelling vertically... + if (theBoid->oldDir.x != 0) { + // calculate gradient of a line _perpendicular_ to its direction (hence the minus) + grad = -theBoid->oldDir.y / theBoid->oldDir.x; + + // calculate where this line hits the y axis (from y = mx + c) + intercept = theBoid->oldPos.y - (grad * theBoid->oldPos.x); + + /* compare the horizontal position of the neighbor boid with */ + /* the point on the line that has its vertical coordinate */ + if (neighbor->oldPos.x >= ((neighbor->oldPos.y - intercept) / grad)) { + /* return true if the first boid's horizontal movement is +ve */ + result = (theBoid->oldDir.x > 0); + + if (result==0) return 0; + else goto next; + + } else { + /* return true if the first boid's horizontal movement is +ve */ + result = (theBoid->oldDir.x < 0); + if (result==0) return 0; + else goto next; + } + } + /* else theBoid is travelling vertically, so just compare vertical coordinates */ + else if (theBoid->oldDir.y > 0) { + result = (neighbor->oldPos.y > theBoid->oldPos.y); + if (result==0){ + return 0; + }else{ + goto next; + } + }else{ + result = (neighbor->oldPos.y < theBoid->oldPos.y); + if (result==0){ + return 0; + } else { + goto next; + } + } +next: +/* + // yz plane + + // if theBoid is not travelling vertically... + if (theBoid->oldDir.y != 0) { + // calculate gradient of a line _perpendicular_ to its direction (hence the minus) + grad = -theBoid->oldDir.z / theBoid->oldDir.y; + + // calculate where this line hits the y axis (from y = mx + c) + intercept = theBoid->oldPos.z - (grad * theBoid->oldPos.y); + + // compare the horizontal position of the neighbor boid with + // the point on the line that has its vertical coordinate + if (neighbor->oldPos.y >= ((neighbor->oldPos.z - intercept) / grad)) { + // return true if the first boid's horizontal movement is +ve + result = (theBoid->oldDir.y > 0); + if (result==0){ + return 0; + }else{ + goto next2; + } + } else { + // return true if the first boid's horizontal movement is +ve + result = (theBoid->oldDir.y < 0); + if (result==0){ + return 0; + }else{ + goto next2; + } + } + } + // else theBoid is travelling vertically, so just compare vertical coordinates + else if (theBoid->oldDir.z > 0) { + result = (neighbor->oldPos.z > theBoid->oldPos.z); + if (result==0){ + return 0; + }else{ + goto next2; + } + }else{ + result = (neighbor->oldPos.z < theBoid->oldPos.z); + if (result==0){ + return 0; + }else{ + goto next2; + } + } +next2: */ + return 1; +} + +void NormalizeVelocity(Velocity *direction) +{ + float my_hypot; + + my_hypot = sqrt(direction->x * direction->x + direction->y * direction->y);// + direction->z * direction->z ); + + if (my_hypot != 0.0) { + direction->x = direction->x / my_hypot; + direction->y = direction->y / my_hypot; + // direction->z = direction->z / my_hypot; + } +} + +double RandomInt(double minRange, double maxRange) +{ + unsigned short qdRdm; + double t, result; + + qdRdm = rand(); + t = (double)qdRdm / 65536.0; // now 0 <= t <= 1 + result = (t * (maxRange - minRange)) + minRange; + return(result); +} + +double DistSqrToPt(Point2d firstPoint, Point2d secondPoint) +{ + double a, b,c; + a = firstPoint.x - secondPoint.x; + b = firstPoint.y - secondPoint.y; + //c = firstPoint.z - secondPoint.z; + return(a * a + b * b); // + c * c); +} \ No newline at end of file diff --git a/boids2d/boids2d-help.pd b/boids2d/boids2d-help.pd deleted file mode 100644 index e48c76b..0000000 --- a/boids2d/boids2d-help.pd +++ /dev/null @@ -1,732 +0,0 @@ -#N canvas 0 31 975 643 10; -#X msg -99 601 dump; -#X msg 266 113 neighbors \$1; -#X floatatom 266 98 5 0 4 0 - neighbors -; -#X floatatom 266 133 5 0 0 0 - maxspeed -; -#X msg 266 148 maxspeed \$1; -#X floatatom 266 168 5 0 0 0 - minspeed -; -#X msg 266 183 minspeed \$1; -#X floatatom 266 203 5 0 0 0 - center -; -#X msg 266 218 center \$1; -#X floatatom 266 238 5 0 0 0 - attract -; -#X msg 266 253 attract \$1; -#X floatatom 266 273 5 0 0 0 - match -; -#X msg 266 288 match \$1; -#X floatatom 266 308 5 0 0 0 - avoid -; -#X msg 266 323 avoid \$1; -#X obj -125 411 r boidParam; -#X floatatom 266 343 5 0 0 0 - repel -; -#X msg 266 358 repel \$1; -#X floatatom 266 378 5 0 0 0 - edgedist -; -#X msg 266 393 edgedist \$1; -#X floatatom 266 413 5 0 0 0 - speed -; -#X msg 266 428 speed \$1; -#X floatatom 266 448 5 0 0 0 - inertia -; -#X msg 266 463 inertia \$1; -#X floatatom 266 483 5 0 0 0 - accel -; -#X msg 266 498 accel \$1; -#X floatatom 266 518 5 0 0 0 - prefdist -; -#X msg 266 533 prefdist \$1; -#X msg -99 620 reset; -#X text 357 148 maximum speed of speed range; -#X text 359 182 minimum speed of speed range; -#X text 356 217 strength of centering instinct; -#X text 358 428 overall speed; -#X text 359 499 speed of acceleration; -#X text 359 530 preferred distance from neighbors; -#X floatatom 267 556 5 0 0 0 - flyrect[0] -; -#X floatatom 306 556 5 0 0 0 - flyrect[1] -; -#X floatatom 345 556 5 0 0 0 - flyrect[2] -; -#X floatatom 384 556 5 0 0 0 - - -; -#X floatatom 266 615 5 0 0 0 - - -; -#X floatatom 306 615 5 0 0 0 - - -; -#X floatatom 266 63 5 0 0 0 - - -; -#X msg 266 78 number \$1; -#X text 357 76 number of boids; -#X floatatom -99 567 5 0 0 0 - - -; -#X msg -99 582 mode \$1; -#X text -35 582 output mode; -#X obj 266 676 s boidParam; -#X obj -99 641 s boidParam; -#X text -35 601 parameter dump; -#X text -36 621 reset boids randomly inside flyrect; -#X text 357 111 number of neighbors each boid consults when flocking -; -#X text 356 288 strength of neighbor speed matching instinct; -#X text 356 323 strength of neighbor avoidance instinct; -#X text 356 355 strength of wall avoidance instinct; -#X text 358 391 distance of vision for avoiding wall edges; -#X text 359 462 willingness to change speed and direction; -#X text 355 251 strength of attraction to 'attractpt'; -#X text -191 84 (c) 1995-98 Eric L. Singer (eric@ericsinger.com); -#X text -191 126 Based on Simon Fraser's implementation of Craig Reynolds' -Boids algorithm. Boids is free for non-commercial use; -#X text -191 159 Boids is a bird flight and animal flock simulator. -It is based on the same algorithm which was used in Jurassic Park for -the herding dinosaurs.; -#X text -191 208 Boids takes an integer argument which is the number -of boids. Each time Boids receives a bang \, it calculates and outputs -the new positions of the boids. The output consists of thew coordiantes -for each boid \, the number and type depending on the mode.; -#X text -190 282 The flight parameters can be changed with messages. -Use the 'dump' message to output a list of the current parameter settings. -; -#X text -190 328 For more information about the Boids algorithm \, -see Craig Reynolds' Web site at "http://reality.sgi.com/employees/craig/boids.html". -; -#X text -188 64 arguments: number of boids \, output -mode; -#X obj -72 460 print dump; -#X obj -203 9 cnv 15 800 48 empty empty boids2d 20 12 2 24 -228915 --66577 0; -#X obj -151 410 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 --1 -1; -#N canvas 430 22 471 383 gem_example 0; -#X msg 33 31 destroy; -#N canvas 494 140 629 324 gemwin 0; -#X obj 219 190 gemwin; -#X obj 66 194 outlet; -#X obj 67 10 inlet; -#X obj 67 41 route create; -#X msg 67 70 set destroy; -#X msg 157 70 set create; -#X msg 350 115 destroy \, reset; -#X msg 238 71 color 0 0 0.5; -#X msg 212 146 create \, 1 \, frame 30 \, color 1 1 1; -#X connect 2 0 3 0; -#X connect 3 0 4 0; -#X connect 3 0 8 0; -#X connect 3 1 5 0; -#X connect 3 1 6 0; -#X connect 4 0 1 0; -#X connect 5 0 1 0; -#X connect 6 0 0 0; -#X connect 7 0 0 0; -#X connect 8 0 0 0; -#X restore 33 51 pd gemwin; -#X obj 33 91 tgl 15 0 empty empty start_flocking_animation 20 6 1 10 --262144 -1 -1 0 1; -#X obj 204 135 r boidParam; -#X obj 33 112 metro 33; -#X floatatom 33 244 5 0 0 0 - - -; -#X floatatom 84 244 5 0 0 0 - - -; -#X obj 86 318 s boidParam; -#N canvas 0 22 466 316 orbit 0; -#X obj 103 82 counter 360; -#X floatatom 103 107 5 0 0 0 - - -; -#X obj 102 204 poltocar; -#X obj 134 169 expr $f1 * (3.141593/180.); -#X obj 103 134 t b f; -#X obj 103 45 inlet; -#X obj 152 254 outlet; -#X obj 96 254 outlet; -#X obj 102 170 1.5; -#X connect 0 0 1 0; -#X connect 1 0 4 0; -#X connect 2 0 6 0; -#X connect 2 1 7 0; -#X connect 3 0 2 1; -#X connect 4 0 8 0; -#X connect 4 1 3 0; -#X connect 5 0 0 0; -#X connect 8 0 2 0; -#X restore 33 222 pd orbit; -#X text 96 30 create/destroy OpenGl context; -#X obj 33 181 spigot; -#X obj 69 160 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 -; -#X obj 339 113 s init; -#X obj 358 84 loadbang; -#X obj 340 85 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#N canvas 0 22 418 379 center 0; -#X obj 101 37 gemhead; -#X obj 99 201 translateXYZ; -#X obj 124 166 unpack 0 0 0; -#X obj 147 94 inlet; -#X msg 240 193 draw line; -#X obj 252 106 loadbang; -#X obj 100 131 alpha; -#X obj 101 68 color 1 0.5 0 0.5; -#X obj 99 228 circle 0.1; -#X connect 0 0 7 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 8 0; -#X connect 5 0 4 0; -#X connect 6 0 1 0; -#X connect 7 0 6 0; -#X restore 32 342 pd center; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 205 224 pd boid; -#X msg 85 295 attractpt \$1 \$2; -#X obj 33 267 pack 0 0; -#X obj 205 163 boids2d 10; -#X obj 206 191 route 0 1 2 3 4 5 6 7 8 9; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 215 234 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 225 244 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 235 254 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 245 264 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 255 274 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 265 284 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 275 294 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 285 304 pd boid; -#N canvas 213 30 518 368 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X obj 192 162 unpack 0 0; -#X connect 0 0 4 0; -#X connect 1 0 7 0; -#X connect 2 0 8 0; -#X connect 3 0 1 0; -#X connect 4 0 3 0; -#X connect 5 0 4 1; -#X connect 5 0 6 0; -#X connect 6 0 3 1; -#X connect 8 0 1 1; -#X connect 8 1 1 2; -#X restore 295 314 pd boid; -#X connect 0 0 1 0; -#X connect 1 0 0 0; -#X connect 2 0 4 0; -#X connect 3 0 19 0; -#X connect 4 0 10 0; -#X connect 4 0 19 0; -#X connect 5 0 18 0; -#X connect 6 0 18 1; -#X connect 8 0 5 0; -#X connect 8 1 6 0; -#X connect 10 0 8 0; -#X connect 11 0 10 1; -#X connect 13 0 12 0; -#X connect 13 0 11 0; -#X connect 14 0 12 0; -#X connect 17 0 7 0; -#X connect 18 0 17 0; -#X connect 18 0 15 0; -#X connect 19 0 20 0; -#X connect 20 0 16 0; -#X connect 20 1 21 0; -#X connect 20 2 22 0; -#X connect 20 3 23 0; -#X connect 20 4 24 0; -#X connect 20 5 25 0; -#X connect 20 6 26 0; -#X connect 20 7 27 0; -#X connect 20 8 28 0; -#X connect 20 9 29 0; -#X restore 57 430 pd gem_example; -#X obj 266 574 pack 0 0 0 0 0 0; -#X obj 266 632 pack 0 0 0; -#X floatatom 345 615 5 0 0 0 - - -; -#X text -190 105 float/2d/3d adaptation 08/2005 by a. sier / jasch -; -#N canvas 754 114 186 470 init 0; -#X obj 34 21 loadbang; -#X obj 94 21 r reset; -#X msg 15 78 \; neighbors 4; -#X msg 15 348 \; speed 3; -#X obj 16 49 b; -#X obj 17 21 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X msg 15 438 \; prefdist 1.5; -#X msg 15 108 \; maxspeed 1.5; -#X msg 15 138 \; minspeed 1.2; -#X msg 15 168 \; center 1.2; -#X msg 15 198 \; attract 1.25; -#X msg 15 228 \; match 0.3; -#X msg 15 288 \; repel 3.5; -#X msg 15 258 \; avoid 3.5; -#X msg 15 318 \; edgedist 3; -#X msg 15 379 \; inertia 4.5; -#X msg 15 408 \; accel 2.5; -#X connect 0 0 4 0; -#X connect 1 0 4 0; -#X connect 4 0 2 0; -#X connect 4 0 7 0; -#X connect 4 0 8 0; -#X connect 4 0 9 0; -#X connect 4 0 10 0; -#X connect 4 0 11 0; -#X connect 4 0 13 0; -#X connect 4 0 12 0; -#X connect 4 0 3 0; -#X connect 4 0 15 0; -#X connect 4 0 16 0; -#X connect 4 0 6 0; -#X connect 5 0 4 0; -#X restore 57 411 pd init; -#X obj -151 438 boids2d 16 0; -#X obj -150 488 print boids2d; -#X msg 266 592 flyrect \$1 \$2 \$3 \$4; -#X msg 266 652 attractpt \$1 \$2; -#X text 389 614 point to which boids are attracted (x/y); -#X text 392 575 bounding box (walls) in which to fly (l/t/r/b); -#N canvas 88 105 494 344 META 0; -#X text 12 165 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan -Wilkes for Pd version 0.42.; -#X text 12 145 AUTHOR Eric L. Singer; -#X text 12 5 KEYWORDS control; -#X text 12 45 DESCRIPTION bird flight and animal flock simulator; -#X text 12 65 INLET_0 bang dump mode reset number neighbors maxspeed -minspeed center attract match avoid repel edgedist speed inertia accel -prefdist flyrect attractpt; -#X text 12 105 OUTLET_0 list; -#X text 12 125 OUTLET_1 list; -#X text 12 25 LICENSE GPL v2; -#X restore 720 676 pd META; -#X connect 0 0 48 0; -#X connect 1 0 47 0; -#X connect 2 0 1 0; -#X connect 3 0 4 0; -#X connect 4 0 47 0; -#X connect 5 0 6 0; -#X connect 6 0 47 0; -#X connect 7 0 8 0; -#X connect 8 0 47 0; -#X connect 9 0 10 0; -#X connect 10 0 47 0; -#X connect 11 0 12 0; -#X connect 12 0 47 0; -#X connect 13 0 14 0; -#X connect 14 0 47 0; -#X connect 15 0 74 0; -#X connect 16 0 17 0; -#X connect 17 0 47 0; -#X connect 18 0 19 0; -#X connect 19 0 47 0; -#X connect 20 0 21 0; -#X connect 21 0 47 0; -#X connect 22 0 23 0; -#X connect 23 0 47 0; -#X connect 24 0 25 0; -#X connect 25 0 47 0; -#X connect 26 0 27 0; -#X connect 27 0 47 0; -#X connect 28 0 48 0; -#X connect 35 0 69 0; -#X connect 36 0 69 1; -#X connect 37 0 69 2; -#X connect 38 0 69 3; -#X connect 39 0 70 0; -#X connect 40 0 70 1; -#X connect 41 0 42 0; -#X connect 42 0 47 0; -#X connect 44 0 45 0; -#X connect 45 0 48 0; -#X connect 67 0 74 0; -#X connect 69 0 76 0; -#X connect 70 0 77 0; -#X connect 71 0 70 2; -#X connect 74 0 75 0; -#X connect 74 1 65 0; -#X connect 76 0 47 0; -#X connect 77 0 47 0; diff --git a/boids2d/boids2d.c b/boids2d/boids2d.c deleted file mode 100644 index 520a3ae..0000000 --- a/boids2d/boids2d.c +++ /dev/null @@ -1,962 +0,0 @@ -/* - - boids2d 08/2005 a.sier / jasch adapted from boids by eric singer 1995-2003 eric l. singer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "m_pd.h" -#include -#include - -// constants -#define kAssistInlet 1 -#define kAssistOutlet 2 -#define kMaxLong 0xFFFFFFFF -#define kMaxNeighbors 4 - -// util -#define MAX(a,b) ((a)>(b)?(a):(b)) -#define CLIP(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x) - -// initial flight parameters -const short kNumBoids = 12; // number of boids -const short kNumNeighbors = 2; // must be <= kMaxNeighbors -const double kMinSpeed = 0.15; // boids' minimum speed -const double kMaxSpeed = 0.25; // boids' maximum speed -const double kCenterWeight = 0.25; // flock centering -const double kAttractWeight = 0.300;// attraction point seeking -const double kMatchWeight = 0.100;// neighbors velocity matching -const double kAvoidWeight = 0.10; // neighbors avoidance -const double kWallsWeight = 0.500;// wall avoidance [210] -const double kEdgeDist = 0.5; // vision distance to avoid wall edges [5] -const double kSpeedupFactor = 0.100;// alter animation speed -const double kInertiaFactor = 0.20; // willingness to change speed & direction -const double kAccelFactor = 0.100;// neighbor avoidance accelerate or decelerate rate -const double kPrefDist = 0.25; // preferred distance from neighbors -const double kFlyRectTop = 1.0; // fly rect boundaries -const double kFlyRectLeft = -1.0; -const double kFlyRectBottom = -1.0; -const double kFlyRectRight = 1.0; -// const double kFlyRectFront = 1.0; -// const double kFlyRectBack = -1.0; - - -// typedefs -typedef struct Velocity { - double x; - double y; -// double z; -} Velocity; - -typedef struct Point2d { - double x; - double y; -// double z; -} Point2d; - -typedef struct Box3D { - double left, right; - double top, bottom; -// double front, back; -} Box3D; - -typedef struct _Boid { - Point2d oldPos; - Point2d newPos; - Velocity oldDir; - Velocity newDir; - double speed; - short neighbor[kMaxNeighbors]; - double neighborDistSqr[kMaxNeighbors]; -} t_one_boid, *BoidPtr; - -typedef struct _FlockObject { - t_object ob; - void *out1, *out2; - short mode; - long numBoids; - long numNeighbors; - Box3D flyRect; - double minSpeed; - double maxSpeed; - double centerWeight; - double attractWeight; - double matchWeight; - double avoidWeight; - double wallsWeight; - double edgeDist; - double speedupFactor; - double inertiaFactor; - double accelFactor; - double prefDist; - double prefDistSqr; - Point2d centerPt; - Point2d attractPt; - BoidPtr boid; - double d2r, r2d; -} t_boids, *FlockPtr; - -// variables -// void *flock; -t_symbol *ps_nothing; - -// prototypes -void *boids2d_class; -void *Flock_new(t_symbol *s, long argc, t_atom *argv); -void Flock_free(t_boids *x); -void Flock_bang(t_boids *x); -void Flock_dump(t_boids *x); -void Flock_mode(t_boids *x, t_float arg); -void Flock_numNeighbors(t_boids *x, t_float arg); -void Flock_numBoids(t_boids *x, t_float arg); -void Flock_minSpeed(t_boids *x, t_float arg); -void Flock_maxSpeed(t_boids *x, t_float arg); -void Flock_centerWeight(t_boids *x, t_float arg); -void Flock_attractWeight(t_boids *x, t_float arg); -void Flock_matchWeight(t_boids *x, t_float arg); -void Flock_avoidWeight(t_boids *x, t_float arg); -void Flock_wallsWeight(t_boids *x, t_float arg); -void Flock_edgeDist(t_boids *x, t_float arg); -void Flock_speedupFactor(t_boids *x, t_float arg); -void Flock_inertiaFactor(t_boids *x, t_float arg); -void Flock_accelFactor(t_boids *x, t_float arg); -void Flock_prefDist(t_boids *x, t_float arg); -void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv); -void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv); -void Flock_reset(t_boids *x); -void Flock_resetBoids(t_boids *x); -void InitFlock(t_boids *x); -void FlightStep(t_boids *x); -Point2d FindFlockCenter(t_boids *x); -float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel); -Velocity SeekPoint(t_boids *x, short theBoid, Point2d seekPt); -Velocity AvoidWalls(t_boids *x, short theBoid); -int InFront(BoidPtr theBoid, BoidPtr neighbor); -void NormalizeVelocity(Velocity *direction); -double RandomInt(double minRange, double maxRange); -double DistSqrToPt(Point2d firstPoint, Point2d secondPoint); - -void boids2d_setup(void) -{ - boids2d_class = class_new(gensym("boids2d"), (t_newmethod)Flock_new, - (t_method)Flock_free, sizeof(t_boids), 0, A_GIMME, 0); - /* setup((t_messlist **) &flock, (method)Flock_new, (method)Flock_free, (short) sizeof(FlockObject), 0L, A_LONG, A_DEFLONG, 0); */ - class_addfloat(boids2d_class, (t_method) Flock_numBoids); - class_addbang(boids2d_class, (t_method) Flock_bang); - class_addmethod(boids2d_class, (t_method) Flock_numNeighbors, gensym("neighbors"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_numBoids, gensym("number"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_mode, gensym("mode"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_minSpeed, gensym("minspeed"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_maxSpeed, gensym("maxspeed"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_centerWeight, gensym("center"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_attractWeight, gensym("attract"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_matchWeight, gensym("match"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_avoidWeight, gensym("avoid"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_wallsWeight, gensym("repel"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_edgeDist, gensym("edgedist"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_speedupFactor, gensym("speed"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_inertiaFactor, gensym("inertia"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_accelFactor, gensym("accel"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_prefDist, gensym("prefdist"), A_FLOAT, 0); - class_addmethod(boids2d_class, (t_method) Flock_flyRect, gensym("flyrect"), A_GIMME, 0); - class_addmethod(boids2d_class, (t_method) Flock_attractPt, gensym("attractpt"), A_GIMME, 0); - class_addmethod(boids2d_class, (t_method) Flock_resetBoids, gensym("reset"), 0); - class_addmethod(boids2d_class, (t_method) Flock_reset, gensym("init"), 0); - class_addmethod(boids2d_class, (t_method) Flock_dump, gensym("dump"), 0); - - post("boids2d 2005-2006 a.sier / jasch 1995-2003 eric l. singer "__DATE__" "__TIME__); - ps_nothing = gensym(""); -} - - -void *Flock_new(t_symbol *s, long argc, t_atom *argv) -{ - t_boids *x = (t_boids *)pd_new(boids2d_class); - x->out1 = outlet_new(&x->ob, NULL); - x->out2 = outlet_new(&x->ob, NULL); - - x->numBoids = 16; - if((argc >= 1) && (argv[0].a_type == A_FLOAT)){ - x->numBoids = argv[0].a_w.w_float; - } - x->boid = (t_one_boid *)malloc(sizeof(t_one_boid) * x->numBoids); - - InitFlock(x); - - x->mode = 0; - if((argc >= 2) && (argv[1].a_type == A_FLOAT)){ - x->mode = (short)(CLIP(argv[1].a_w.w_float, 0, 2)); - } - - x->d2r = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068/180.0; - x->r2d = 180.0/3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068; - - return(x); -} - - -void Flock_free(t_boids *x) -{ - free(x->boid); -} - -void Flock_bang(t_boids *x) -{ - short i; - t_atom outlist[10]; - t_atom *out; - - double tempNew_x, tempNew_y; - double tempOld_x, tempOld_y; - double delta_x, delta_y; - double azi, speed; - // double tempspeed; - - out = outlist; - - FlightStep(x); - - - switch(x->mode) { // newpos - case 0: - for (i = 0; i < x->numBoids; i++){ - SETFLOAT(out+0, i); - SETFLOAT(out+1, x->boid[i].newPos.x); - SETFLOAT(out+2, x->boid[i].newPos.y); - // SETFLOAT(out+3, x->boid[i].newPos.z); - outlet_list(x->out1, 0L, 3, out); - } - break; - case 1: //newpos + oldpos - for (i = 0; i < x->numBoids; i++){ - SETFLOAT(out+0, i); - SETFLOAT(out+1, x->boid[i].newPos.x); - SETFLOAT(out+2, x->boid[i].newPos.y); - // SETFLOAT(out+3, x->boid[i].newPos.z); - SETFLOAT(out+3, x->boid[i].oldPos.x); - SETFLOAT(out+4, x->boid[i].oldPos.y); - // SETFLOAT(out+6, x->boid[i].oldPos.z); - outlet_list(x->out1, 0L, 5, out); - } - break; - case 2: - for (i = 0; i < x->numBoids; i++){ - tempNew_x = x->boid[i].newPos.x; - tempNew_y = x->boid[i].newPos.y; - // tempNew_z = x->boid[i].newPos.z; - tempOld_x = x->boid[i].oldPos.x; - tempOld_y = x->boid[i].oldPos.y; - // tempOld_z = x->boid[i].oldPos.z; - delta_x = tempNew_x - tempOld_x; - delta_y = tempNew_y - tempOld_y; - // delta_z = tempNew_z - tempOld_z; - azi = atan2(delta_y, delta_x) * x->r2d; - // ele = atan2(delta_y, delta_x) * x->r2d; - speed = sqrt(delta_x * delta_x + delta_y * delta_y);// + delta_z * delta_z); - SETFLOAT(out+0, i); - SETFLOAT(out+1, tempNew_x); - SETFLOAT(out+2, tempNew_y); - // SETFLOAT(out+3, tempNew_z); - SETFLOAT(out+3, tempOld_x); - SETFLOAT(out+4, tempOld_y); - // SETFLOAT(out+6, tempOld_z); - SETFLOAT(out+5, speed); - SETFLOAT(out+6, azi); - // SETFLOAT(out+9, ele); - outlet_list(x->out1, 0L, 7, out); - } - break; - } -} - -void Flock_dump(t_boids *x) -{ - t_atom outList[6]; - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->numNeighbors; - outlet_anything(x->out2, gensym("neighbors"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->minSpeed; - outlet_anything(x->out2, gensym("minspeed"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->maxSpeed; - outlet_anything(x->out2, gensym("maxspeed"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->centerWeight; - outlet_anything(x->out2, gensym("center"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->attractWeight; - outlet_anything(x->out2, gensym("attract"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->matchWeight; - outlet_anything(x->out2, gensym("match"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->avoidWeight; - outlet_anything(x->out2, gensym("avoid"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->wallsWeight; - outlet_anything(x->out2, gensym("repel"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->edgeDist; - outlet_anything(x->out2, gensym("edgedist"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->speedupFactor; - outlet_anything(x->out2, gensym("speed"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->inertiaFactor; - outlet_anything(x->out2, gensym("inertia"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->accelFactor; - outlet_anything(x->out2, gensym("accel"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->prefDist; - outlet_anything(x->out2, gensym("prefdist"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->flyRect.left; - outList[1].a_type = A_FLOAT; - outList[1].a_w.w_float = x->flyRect.top; - outList[2].a_type = A_FLOAT; - outList[2].a_w.w_float = x->flyRect.right; - outList[3].a_type = A_FLOAT; - outList[3].a_w.w_float = x->flyRect.bottom; - /*outList[4].a_type = A_FLOAT; - outList[4].a_w.w_float = x->flyRect.front; - outList[5].a_type = A_FLOAT; - outList[5].a_w.w_float = x->flyRect.back;*/ - outlet_anything(x->out2, gensym("flyrect"), 4, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->attractPt.x; - outList[1].a_type = A_FLOAT; - outList[1].a_w.w_float = x->attractPt.y; - /*outList[2].a_type = A_FLOAT; - outList[2].a_w.w_float = x->attractPt.z;*/ - outlet_anything(x->out2, gensym("attractpt"), 2, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->mode; - outlet_anything(x->out2, gensym("mode"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->numBoids; - outlet_anything(x->out2, gensym("number"), 1, outList); -} - - -void Flock_mode(t_boids *x, t_float arg) -{ - long m = (long)arg; - x->mode = CLIP(m, 0, 2); -} - -void Flock_numNeighbors(t_boids *x, t_float arg) -{ - x->numNeighbors = (long)arg; -} - -void Flock_numBoids(t_boids *x, t_float arg) -{ - x->boid = (t_one_boid *)realloc(x->boid, sizeof(t_one_boid) * (long)arg); - x->numBoids = (long)arg; - Flock_resetBoids(x); -} - -void Flock_minSpeed(t_boids *x, t_float arg) -{ - x->minSpeed = MAX(arg, 0.000001); -} - -void Flock_maxSpeed(t_boids *x, t_float arg) -{ - x->maxSpeed = (double)arg; -} - -void Flock_centerWeight(t_boids *x, t_float arg) -{ - x->centerWeight = (double)arg; -} - -void Flock_attractWeight(t_boids *x, t_float arg) -{ - x->attractWeight = (double)arg; -} - -void Flock_matchWeight(t_boids *x, t_float arg) -{ - x->matchWeight = (double)arg; -} - -void Flock_avoidWeight(t_boids *x, t_float arg) -{ - x->avoidWeight = (double)arg; -} - -void Flock_wallsWeight(t_boids *x, t_float arg) -{ - x->wallsWeight = (double)arg; -} - -void Flock_edgeDist(t_boids *x, t_float arg) -{ - x->edgeDist = (double)arg; -} - -void Flock_speedupFactor(t_boids *x, t_float arg) -{ - x->speedupFactor = (double)arg; -} - -void Flock_inertiaFactor(t_boids *x, t_float arg) -{ - if(arg == 0){ - x->inertiaFactor = 0.000001; - }else{ - x->inertiaFactor = (double)arg; - } -} - -void Flock_accelFactor(t_boids *x, t_float arg) -{ - x->accelFactor = (double)arg; -} - -void Flock_prefDist(t_boids *x, t_float arg) -{ - x->prefDist = (double)arg; -} - -void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv) -{ - double temp[4]; - short i; - if(argc == 4){ - for(i=0;i<4;i++) { - if(argv[i].a_type == A_FLOAT) { - temp[i] = (double)argv[i].a_w.w_float; - } - } - x->flyRect.left = temp[0]; - x->flyRect.top = temp[1]; - x->flyRect.right = temp[2]; - x->flyRect.bottom = temp[3]; - // x->flyRect.front = temp[4]; - // x->flyRect.back = temp[5]; - }else{ - error("boids2d: flyrect needs four values"); - } -} - -void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv) -{ - double temp[2]; - short i; - if(argc == 2){ - for(i=0;i<2;i++) { - if(argv[i].a_type == A_FLOAT) { - temp[i] = (double)argv[i].a_w.w_float; - } - } - x->attractPt.x = temp[0]; - x->attractPt.y = temp[1]; - // x->attractPt.z = temp[2]; - }else{ - error("boids2d: attractPt needs two values"); - } -} - -void Flock_reset(t_boids *x) -{ - InitFlock(x); -} - -void Flock_resetBoids(t_boids *x) -{ - long i, j; - double rndAngle; - - for (i = 0; i < x->numBoids; i++) { // init everything to 0.0 - x->boid[i].oldPos.x = 0.0; - x->boid[i].oldPos.y = 0.0; - // x->boid[i].oldPos.z = 0.0; - - x->boid[i].newPos.x = 0.0; - x->boid[i].newPos.y = 0.0; - // x->boid[i].newPos.z = 0.0; - - x->boid[i].oldDir.x = 0.0; - x->boid[i].oldDir.y = 0.0; - // x->boid[i].oldDir.z = 0.0; - - x->boid[i].newDir.x = 0.0; - x->boid[i].newDir.y = 0.0; - // x->boid[i].newDir.z = 0.0; - - x->boid[i].speed = 0.0; - - for(j=0; jboid[i].neighbor[j] = 0; - x->boid[i].neighborDistSqr[j] = 0.0; - } - } - for (i = 0; i < x->numBoids; i++) { // set the initial locations and velocities of the boids - x->boid[i].newPos.x = x->boid[i].oldPos.x = RandomInt(x->flyRect.right,x->flyRect.left); // set random location within flyRect - x->boid[i].newPos.y = x->boid[i].oldPos.y = RandomInt(x->flyRect.bottom, x->flyRect.top); - // x->boid[i].newPos.z = x->boid[i].oldPos.z = RandomInt(x->flyRect.back, x->flyRect.front); - rndAngle = RandomInt(0, 360) * x->d2r; // set velocity from random angle - x->boid[i].newDir.x = sin(rndAngle); - x->boid[i].newDir.y = cos(rndAngle); - // x->boid[i].newDir.z = (cos(rndAngle) + sin(rndAngle)) * 0.5; - x->boid[i].speed = (kMaxSpeed + kMinSpeed) * 0.5; - } -} - -void InitFlock(t_boids *x) -{ - x->numNeighbors = kNumNeighbors; - x->minSpeed = kMinSpeed; - x->maxSpeed = kMaxSpeed; - x->centerWeight = kCenterWeight; - x->attractWeight = kAttractWeight; - x->matchWeight = kMatchWeight; - x->avoidWeight = kAvoidWeight; - x->wallsWeight = kWallsWeight; - x->edgeDist = kEdgeDist; - x->speedupFactor = kSpeedupFactor; - x->inertiaFactor = kInertiaFactor; - x->accelFactor = kAccelFactor; - x->prefDist = kPrefDist; - x->prefDistSqr = kPrefDist * kPrefDist; - x->flyRect.top = kFlyRectTop; - x->flyRect.left = kFlyRectLeft; - x->flyRect.bottom = kFlyRectBottom; - x->flyRect.right = kFlyRectRight; - // x->flyRect.front = kFlyRectFront; - // x->flyRect.back = kFlyRectBack; - x->attractPt.x = (kFlyRectLeft + kFlyRectRight) * 0.5; - x->attractPt.y = (kFlyRectTop + kFlyRectBottom) * 0.5; - // x->attractPt.z = (kFlyRectFront + kFlyRectBack) * 0.5; - Flock_resetBoids(x); -} - -void FlightStep(t_boids *x) -{ - Velocity goCenterVel; - Velocity goAttractVel; - Velocity matchNeighborVel; - Velocity avoidWallsVel; - Velocity avoidNeighborVel; - float avoidNeighborSpeed; - const Velocity zeroVel = {0.0, 0.0};//, 0.0}; - short i; - - x->centerPt = FindFlockCenter(x); - for (i = 0; i < x->numBoids; i++) { // save position and velocity - x->boid[i].oldPos.x = x->boid[i].newPos.x; - x->boid[i].oldPos.y = x->boid[i].newPos.y; - // x->boid[i].oldPos.z = x->boid[i].newPos.z; - - x->boid[i].oldDir.x = x->boid[i].newDir.x; - x->boid[i].oldDir.y = x->boid[i].newDir.y; - // x->boid[i].oldDir.z = x->boid[i].newDir.z; - } - for (i = 0; i < x->numBoids; i++) { - if (x->numNeighbors > 0) { // get all velocity components - avoidNeighborSpeed = MatchAndAvoidNeighbors(x, i,&matchNeighborVel, &avoidNeighborVel); - } else { - matchNeighborVel = zeroVel; - avoidNeighborVel = zeroVel; - avoidNeighborSpeed = 0; - } - goCenterVel = SeekPoint(x, i, x->centerPt); - goAttractVel = SeekPoint(x, i, x->attractPt); - avoidWallsVel = AvoidWalls(x, i); - - // compute resultant velocity using weights and inertia - x->boid[i].newDir.x = x->inertiaFactor * (x->boid[i].oldDir.x) + - (x->centerWeight * goCenterVel.x + - x->attractWeight * goAttractVel.x + - x->matchWeight * matchNeighborVel.x + - x->avoidWeight * avoidNeighborVel.x + - x->wallsWeight * avoidWallsVel.x) / x->inertiaFactor; - x->boid[i].newDir.y = x->inertiaFactor * (x->boid[i].oldDir.y) + - (x->centerWeight * goCenterVel.y + - x->attractWeight * goAttractVel.y + - x->matchWeight * matchNeighborVel.y + - x->avoidWeight * avoidNeighborVel.y + - x->wallsWeight * avoidWallsVel.y) / x->inertiaFactor; - /*x->boid[i].newDir.z = x->inertiaFactor * (x->boid[i].oldDir.z) + - (x->centerWeight * goCenterVel.z + - x->attractWeight * goAttractVel.z + - x->matchWeight * matchNeighborVel.z + - x->avoidWeight * avoidNeighborVel.z + - x->wallsWeight * avoidWallsVel.z) / x->inertiaFactor;*/ - NormalizeVelocity(&(x->boid[i].newDir)); // normalize velocity so its length is unity - - // set to avoidNeighborSpeed bounded by minSpeed and maxSpeed - if ((avoidNeighborSpeed >= x->minSpeed) && - (avoidNeighborSpeed <= x->maxSpeed)) - x->boid[i].speed = avoidNeighborSpeed; - else if (avoidNeighborSpeed > x->maxSpeed) - x->boid[i].speed = x->maxSpeed; - else - x->boid[i].speed = x->minSpeed; - - // calculate new position, applying speedupFactor - x->boid[i].newPos.x += x->boid[i].newDir.x * x->boid[i].speed * (x->speedupFactor / 100.0); - x->boid[i].newPos.y += x->boid[i].newDir.y * x->boid[i].speed * (x->speedupFactor / 100.0); - // x->boid[i].newPos.z += x->boid[i].newDir.z * x->boid[i].speed * (x->speedupFactor / 100.0); - - } -} - -Point2d FindFlockCenter(t_boids *x) -{ - double totalH = 0, totalV = 0, totalD = 0; - Point2d centerPoint; - short i; - - for (i = 0 ; i < x->numBoids; i++) - { - totalH += x->boid[i].oldPos.x; - totalV += x->boid[i].oldPos.y; - // totalD += x->boid[i].oldPos.z; - } - centerPoint.x = (double)(totalH / x->numBoids); - centerPoint.y = (double)(totalV / x->numBoids); - // centerPoint.z = (double) (totalD / x->numBoids); - - return(centerPoint); -} - -float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel) -{ - short i, j, neighbor; - double distSqr; - double dist, distH, distV,distD; - double tempSpeed; - short numClose = 0; - Velocity totalVel = {0.0,0.0};//,0.0}; - - /**********************/ - /* Find the neighbors */ - /**********************/ - - /* special case of one neighbor */ - if (x->numNeighbors == 1) { - x->boid[theBoid].neighborDistSqr[0] = kMaxLong; - - for (i = 0; i < x->numBoids; i++) { - if (i != theBoid) { - distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); - - /* if this one is closer than the closest so far, then remember it */ - if (x->boid[theBoid].neighborDistSqr[0] > distSqr) { - x->boid[theBoid].neighborDistSqr[0] = distSqr; - x->boid[theBoid].neighbor[0] = i; - } - } - } - } - /* more than one neighbor */ - else { - for (j = 0; j < x->numNeighbors; j++) - x->boid[theBoid].neighborDistSqr[j] = kMaxLong; - - for (i = 0 ; i < x->numBoids; i++) { - /* if this one is not me... */ - if (i != theBoid) { - distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); - - /* if distSqr is less than the distance at the bottom of the array, sort into array */ - if (distSqr < x->boid[theBoid].neighborDistSqr[x->numNeighbors-1]) { - j = x->numNeighbors - 1; - - /* sort distSqr in to keep array in size order, smallest first */ - while ((distSqr < x->boid[theBoid].neighborDistSqr[j-1]) && (j > 0)) { - x->boid[theBoid].neighborDistSqr[j] = x->boid[theBoid].neighborDistSqr[j - 1]; - x->boid[theBoid].neighbor[j] = x->boid[theBoid].neighbor[j - 1]; - j--; - } - x->boid[theBoid].neighborDistSqr[j] = distSqr; - x->boid[theBoid].neighbor[j] = i; - } - } - } - } - - /*********************************/ - /* Match and avoid the neighbors */ - /*********************************/ - - matchNeighborVel->x = 0; - matchNeighborVel->y = 0; - // matchNeighborVel->z = 0; - - // set tempSpeed to old speed - tempSpeed = x->boid[theBoid].speed; - - for (i = 0; i < x->numNeighbors; i++) { - neighbor = x->boid[theBoid].neighbor[i]; - - // calculate matchNeighborVel by averaging the neighbor velocities - matchNeighborVel->x += x->boid[neighbor].oldDir.x; - matchNeighborVel->y += x->boid[neighbor].oldDir.y; - // matchNeighborVel->z += x->boid[neighbor].oldDir.z; - - // if distance is less than preferred distance, then neighbor influences boid - distSqr = x->boid[theBoid].neighborDistSqr[i]; - if (distSqr < x->prefDistSqr) { - dist = sqrt(distSqr); - - distH = x->boid[neighbor].oldPos.x - x->boid[theBoid].oldPos.x; - distV = x->boid[neighbor].oldPos.y - x->boid[theBoid].oldPos.y; - // distD = x->boid[neighbor].oldPos.z - x->boid[theBoid].oldPos.z; - - if(dist == 0.0) dist = 0.0000001; - totalVel.x = totalVel.x - distH - (distH * ((float) x->prefDist / (dist))); - totalVel.y = totalVel.y - distV - (distV * ((float) x->prefDist / (dist))); - // totalVel.z = totalVel.z - distD - (distV * ((float) x->prefDist / (dist))); - - numClose++; - } - if (InFront(&(x->boid[theBoid]), &(x->boid[neighbor]))) { // adjust speed - if (distSqr < x->prefDistSqr) - tempSpeed /= (x->accelFactor / 100.0); - else - tempSpeed *= (x->accelFactor / 100.0); - } - else { - if (distSqr < x->prefDistSqr) - tempSpeed *= (x->accelFactor / 100.0); - else - tempSpeed /= (x->accelFactor / 100.0); - } - } - if (numClose) { - avoidNeighborVel->x = totalVel.x / numClose; - avoidNeighborVel->y = totalVel.y / numClose; - // avoidNeighborVel->z = totalVel.z / numClose; - NormalizeVelocity(matchNeighborVel); - } - else { - avoidNeighborVel->x = 0; - avoidNeighborVel->y = 0; - // avoidNeighborVel->z = 0; - } - return(tempSpeed); -} - - -Velocity SeekPoint(t_boids *x, short theBoid, Point2d seekPt) -{ - Velocity tempDir; - tempDir.x = seekPt.x - x->boid[theBoid].oldPos.x; - tempDir.y = seekPt.y - x->boid[theBoid].oldPos.y; - // tempDir.z = seekPt.z - x->boid[theBoid].oldPos.z; - NormalizeVelocity(&tempDir); - return(tempDir); -} - - -Velocity AvoidWalls(t_boids *x, short theBoid) -{ - Point2d testPoint; - Velocity tempVel = {0.0, 0.0};//, 0.0}; - - /* calculate test point in front of the nose of the boid */ - /* distance depends on the boid's speed and the avoid edge constant */ - testPoint.x = x->boid[theBoid].oldPos.x + x->boid[theBoid].oldDir.x * x->boid[theBoid].speed * x->edgeDist; - testPoint.y = x->boid[theBoid].oldPos.y + x->boid[theBoid].oldDir.y * x->boid[theBoid].speed * x->edgeDist; - // testPoint.z = x->boid[theBoid].oldPos.z + x->boid[theBoid].oldDir.z * x->boid[theBoid].speed * x->edgeDist; - - /* if test point is out of the left (right) side of x->flyRect, */ - /* return a positive (negative) horizontal velocity component */ - if (testPoint.x < x->flyRect.left) - tempVel.x = fabs(x->boid[theBoid].oldDir.x); - else if (testPoint.x > x->flyRect.right) - tempVel.x = - fabs(x->boid[theBoid].oldDir.x); - - /* same with top and bottom */ - if (testPoint.y < x->flyRect.top) - tempVel.y = fabs(x->boid[theBoid].oldDir.y); - else if (testPoint.y > x->flyRect.bottom) - tempVel.y = - fabs(x->boid[theBoid].oldDir.y); - - /* same with front and back - if (testPoint.z < x->flyRect.front) - tempVel.z = fabs(x->boid[theBoid].oldDir.z); - else if (testPoint.z > x->flyRect.back) - tempVel.z = - fabs(x->boid[theBoid].oldDir.z); - */ - - return(tempVel); -} - - -int InFront(BoidPtr theBoid, BoidPtr neighbor) -{ - float grad, intercept; - int result; - -/* - -Find the gradient and y-intercept of a line passing through theBoid's oldPos -perpendicular to its direction of motion. Another boid is in front of theBoid -if it is to the right or left of this linedepending on whether theBoid is moving -right or left. However, if theBoid is travelling vertically then just compare -their vertical coordinates. - -*/ - // xy plane - - // if theBoid is not travelling vertically... - if (theBoid->oldDir.x != 0) { - // calculate gradient of a line _perpendicular_ to its direction (hence the minus) - grad = -theBoid->oldDir.y / theBoid->oldDir.x; - - // calculate where this line hits the y axis (from y = mx + c) - intercept = theBoid->oldPos.y - (grad * theBoid->oldPos.x); - - /* compare the horizontal position of the neighbor boid with */ - /* the point on the line that has its vertical coordinate */ - if (neighbor->oldPos.x >= ((neighbor->oldPos.y - intercept) / grad)) { - /* return true if the first boid's horizontal movement is +ve */ - result = (theBoid->oldDir.x > 0); - - if (result==0) return 0; - else goto next; - - } else { - /* return true if the first boid's horizontal movement is +ve */ - result = (theBoid->oldDir.x < 0); - if (result==0) return 0; - else goto next; - } - } - /* else theBoid is travelling vertically, so just compare vertical coordinates */ - else if (theBoid->oldDir.y > 0) { - result = (neighbor->oldPos.y > theBoid->oldPos.y); - if (result==0){ - return 0; - }else{ - goto next; - } - }else{ - result = (neighbor->oldPos.y < theBoid->oldPos.y); - if (result==0){ - return 0; - } else { - goto next; - } - } -next: -/* - // yz plane - - // if theBoid is not travelling vertically... - if (theBoid->oldDir.y != 0) { - // calculate gradient of a line _perpendicular_ to its direction (hence the minus) - grad = -theBoid->oldDir.z / theBoid->oldDir.y; - - // calculate where this line hits the y axis (from y = mx + c) - intercept = theBoid->oldPos.z - (grad * theBoid->oldPos.y); - - // compare the horizontal position of the neighbor boid with - // the point on the line that has its vertical coordinate - if (neighbor->oldPos.y >= ((neighbor->oldPos.z - intercept) / grad)) { - // return true if the first boid's horizontal movement is +ve - result = (theBoid->oldDir.y > 0); - if (result==0){ - return 0; - }else{ - goto next2; - } - } else { - // return true if the first boid's horizontal movement is +ve - result = (theBoid->oldDir.y < 0); - if (result==0){ - return 0; - }else{ - goto next2; - } - } - } - // else theBoid is travelling vertically, so just compare vertical coordinates - else if (theBoid->oldDir.z > 0) { - result = (neighbor->oldPos.z > theBoid->oldPos.z); - if (result==0){ - return 0; - }else{ - goto next2; - } - }else{ - result = (neighbor->oldPos.z < theBoid->oldPos.z); - if (result==0){ - return 0; - }else{ - goto next2; - } - } -next2: */ - return 1; -} - -void NormalizeVelocity(Velocity *direction) -{ - float my_hypot; - - my_hypot = sqrt(direction->x * direction->x + direction->y * direction->y);// + direction->z * direction->z ); - - if (my_hypot != 0.0) { - direction->x = direction->x / my_hypot; - direction->y = direction->y / my_hypot; - // direction->z = direction->z / my_hypot; - } -} - -double RandomInt(double minRange, double maxRange) -{ - unsigned short qdRdm; - double t, result; - - qdRdm = rand(); - t = (double)qdRdm / 65536.0; // now 0 <= t <= 1 - result = (t * (maxRange - minRange)) + minRange; - return(result); -} - -double DistSqrToPt(Point2d firstPoint, Point2d secondPoint) -{ - double a, b,c; - a = firstPoint.x - secondPoint.x; - b = firstPoint.y - secondPoint.y; - //c = firstPoint.z - secondPoint.z; - return(a * a + b * b); // + c * c); -} \ No newline at end of file diff --git a/boids2d/makefile b/boids2d/makefile deleted file mode 100644 index 6198c49..0000000 --- a/boids2d/makefile +++ /dev/null @@ -1,92 +0,0 @@ -NAME=boids2d -CSYM=boids2d - -current: pd_darwin - -# ----------------------- NT ----------------------- - -pd_nt: $(NAME).dll - -.SUFFIXES: .dll - -PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo -VC="C:\Program Files\Microsoft Visual Studio\Vc98" - -PDNTINCLUDE = /I. /I..\..\src /I$(VC)\include - -PDNTLDIR = $(VC)\lib -PDNTLIB = $(PDNTLDIR)\libc.lib \ - $(PDNTLDIR)\oldnames.lib \ - $(PDNTLDIR)\kernel32.lib \ - ..\..\bin\pd.lib - -.c.dll: - cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c - link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) - -# ----------------------- IRIX 5.x ----------------------- - -pd_irix5: $(NAME).pd_irix5 - -.SUFFIXES: .pd_irix5 - -SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 - -SGIINCLUDE = -I../../src - -.c.pd_irix5: - $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c - ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o - rm $*.o - -# ----------------------- IRIX 6.x ----------------------- - -pd_irix6: $(NAME).pd_irix6 - -.SUFFIXES: .pd_irix6 - -SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ - -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ - -Ofast=ip32 - -.c.pd_irix6: - $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c - ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o - rm $*.o - -# ----------------------- LINUX i386 ----------------------- - -pd_linux: $(NAME).pd_linux - -.SUFFIXES: .pd_linux - -LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \ - -Wall -W -Wshadow -Wstrict-prototypes \ - -Wno-unused -Wno-parentheses -Wno-switch $(CFLAGS) - -LINUXINCLUDE = -I../../src - -.c.pd_linux: - $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - ld --export-dynamic -shared -o $*.pd_linux $*.o -lc -lm - strip --strip-unneeded $*.pd_linux - rm -f $*.o - -# ----------------------- Mac OSX ----------------------- - -pd_darwin: $(NAME).pd_darwin - -.SUFFIXES: .pd_darwin - -DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ - -Wno-unused -Wno-parentheses -Wno-switch - -.c.pd_darwin: - $(CC) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - $(CC) -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o - rm -f $*.o - -# ---------------------------------------------------------- - -clean: - rm -f *.o *.pd_* so_locations diff --git a/boids3d-help.pd b/boids3d-help.pd new file mode 100644 index 0000000..95acaf0 --- /dev/null +++ b/boids3d-help.pd @@ -0,0 +1,2101 @@ +#N canvas 0 31 963 634 10; +#X declare -lib jasch_lib; +#X msg -99 601 dump; +#X msg 266 113 neighbors \$1; +#X floatatom 266 98 5 0 4 0 - neighbors -; +#X floatatom 266 133 5 0 0 0 - maxspeed -; +#X msg 266 148 maxspeed \$1; +#X floatatom 266 168 5 0 0 0 - minspeed -; +#X msg 266 183 minspeed \$1; +#X floatatom 266 203 5 0 0 0 - center -; +#X msg 266 218 center \$1; +#X floatatom 266 238 5 0 0 0 - attract -; +#X msg 266 253 attract \$1; +#X floatatom 266 273 5 0 0 0 - match -; +#X msg 266 288 match \$1; +#X floatatom 266 308 5 0 0 0 - avoid -; +#X msg 266 323 avoid \$1; +#X obj -125 411 r boidParam; +#X floatatom 266 343 5 0 0 0 - repel -; +#X msg 266 358 repel \$1; +#X floatatom 266 378 5 0 0 0 - edgedist -; +#X msg 266 393 edgedist \$1; +#X floatatom 266 413 5 0 0 0 - speed -; +#X msg 266 428 speed \$1; +#X floatatom 266 448 5 0 0 0 - inertia -; +#X msg 266 463 inertia \$1; +#X floatatom 266 483 5 0 0 0 - accel -; +#X msg 266 498 accel \$1; +#X floatatom 266 518 5 0 0 0 - prefdist -; +#X msg 266 533 prefdist \$1; +#X msg -99 620 reset; +#X text 357 148 maximum speed of speed range; +#X text 359 182 minimum speed of speed range; +#X text 356 217 strength of centering instinct; +#X text 358 428 overall speed; +#X text 359 499 speed of acceleration; +#X text 359 530 preferred distance from neighbors; +#X floatatom 267 556 5 0 0 0 - flyrect[0] -; +#X floatatom 306 556 5 0 0 0 - flyrect[1] -; +#X floatatom 345 556 5 0 0 0 - flyrect[2] -; +#X floatatom 384 556 5 0 0 0 - - -; +#X floatatom 266 615 5 0 0 0 - - -; +#X floatatom 306 615 5 0 0 0 - - -; +#X floatatom 266 63 5 0 0 0 - - -; +#X msg 266 78 number \$1; +#X text 357 76 number of boids; +#X floatatom -99 567 5 0 0 0 - - -; +#X msg -99 582 mode \$1; +#X text -35 582 output mode; +#X obj 266 676 s boidParam; +#X obj -99 641 s boidParam; +#X text -35 601 parameter dump; +#X text -36 621 reset boids randomly inside flyrect; +#X text 357 111 number of neighbors each boid consults when flocking +; +#X text 356 288 strength of neighbor speed matching instinct; +#X text 356 323 strength of neighbor avoidance instinct; +#X text 356 355 strength of wall avoidance instinct; +#X text 358 391 distance of vision for avoiding wall edges; +#X text 359 462 willingness to change speed and direction; +#X text 355 251 strength of attraction to 'attractpt'; +#X text -191 84 (c) 1995-98 Eric L. Singer (eric@ericsinger.com); +#X text -191 126 Based on Simon Fraser's implementation of Craig Reynolds' +Boids algorithm. Boids is free for non-commercial use; +#X text -191 159 Boids is a bird flight and animal flock simulator. +It is based on the same algorithm which was used in Jurassic Park for +the herding dinosaurs.; +#X text -190 282 The flight parameters can be changed with messages. +Use the 'dump' message to output a list of the current parameter settings. +; +#X text -190 328 For more information about the Boids algorithm \, +see Craig Reynolds' Web site at "http://reality.sgi.com/employees/craig/boids.html". +; +#X text -188 64 arguments: number of boids \, output +mode; +#X obj -72 460 print dump; +#X obj -203 9 cnv 15 800 48 empty empty boids3d 20 12 2 24 -228915 +-66577 0; +#X obj -151 410 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 +-1 -1; +#N canvas 241 22 783 706 gem_example 0; +#X msg 33 31 create; +#N canvas 494 140 629 324 gemwin 0; +#X obj 219 190 gemwin; +#X obj 66 194 outlet; +#X obj 67 10 inlet; +#X obj 67 41 route create; +#X msg 67 70 set destroy; +#X msg 157 70 set create; +#X msg 350 115 destroy \, reset; +#X msg 238 71 color 0 0 0.5; +#X msg 212 146 create \, 1 \, frame 30 \, color 1 1 1; +#X connect 2 0 3 0; +#X connect 3 0 4 0; +#X connect 3 0 8 0; +#X connect 3 1 5 0; +#X connect 3 1 6 0; +#X connect 4 0 1 0; +#X connect 5 0 1 0; +#X connect 6 0 0 0; +#X connect 7 0 0 0; +#X connect 8 0 0 0; +#X restore 33 51 pd gemwin; +#X obj 33 91 tgl 15 0 empty empty start_flocking_animation 20 6 1 10 +-262144 -1 -1 0 1; +#X obj 204 135 r boidParam; +#X obj 33 112 metro 33; +#X floatatom 33 244 5 0 0 0 - - -; +#X floatatom 84 244 5 0 0 0 - - -; +#X obj 86 318 s boidParam; +#N canvas 0 22 466 316 orbit 0; +#X obj 103 82 counter 360; +#X floatatom 103 107 5 0 0 0 - - -; +#X obj 102 204 poltocar; +#X obj 134 169 expr $f1 * (3.141593/180.); +#X obj 103 134 t b f; +#X obj 103 45 inlet; +#X obj 152 254 outlet; +#X obj 96 254 outlet; +#X obj 102 170 1.5; +#X connect 0 0 1 0; +#X connect 1 0 4 0; +#X connect 2 0 6 0; +#X connect 2 1 7 0; +#X connect 3 0 2 1; +#X connect 4 0 8 0; +#X connect 4 1 3 0; +#X connect 5 0 0 0; +#X connect 8 0 2 0; +#X restore 33 222 pd orbit; +#X text 96 30 create/destroy OpenGl context; +#X obj 33 181 spigot; +#X obj 69 160 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 +; +#X obj 339 113 s init; +#X obj 358 84 loadbang; +#X obj 340 85 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 33 267 pack 0 0 0; +#X msg 85 295 attractpt \$1 \$2 \$3; +#N canvas 0 22 414 375 center 0; +#X obj 101 37 gemhead; +#X obj 99 201 translateXYZ; +#X obj 124 166 unpack 0 0 0; +#X obj 147 94 inlet; +#X msg 240 193 draw line; +#X obj 252 106 loadbang; +#X obj 100 131 alpha; +#X obj 101 68 color 1 0.5 0 0.5; +#X obj 99 228 circle 0.1; +#X connect 0 0 7 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 8 0; +#X connect 5 0 4 0; +#X connect 6 0 1 0; +#X connect 7 0 6 0; +#X restore 32 342 pd center; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 206 227 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 216 237 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 226 247 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 236 257 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 246 267 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 256 277 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 266 287 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 276 297 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 286 307 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 296 317 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 306 327 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 316 337 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 326 347 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 336 357 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 346 367 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 356 377 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 366 387 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 376 397 pd boid; +#N canvas 213 30 510 360 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 386 407 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 396 417 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 406 427 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 416 437 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 426 447 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 436 457 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 446 467 pd boid; +#X obj 205 163 boids3d 40; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 456 477 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 466 487 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 476 497 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 486 507 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 496 517 pd boid; +#X obj 206 189 route 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 506 527 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 516 537 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 526 547 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 536 557 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 546 567 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 556 577 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 566 587 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 576 597 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 586 607 pd boid; +#N canvas 213 30 514 364 boid 0; +#X obj 100 24 gemhead; +#X obj 99 201 translateXYZ; +#X obj 192 162 unpack 0 0 0; +#X obj 192 1 inlet; +#X obj 100 155 alpha; +#X obj 101 85 color 1 0.5 0 0.5; +#N canvas 0 22 474 324 rand_color 0; +#X obj 47 130 random 1000; +#X obj 48 171 * 0.001; +#X obj 131 130 random 1000; +#X obj 132 171 * 0.001; +#X obj 214 131 random 1000; +#X obj 215 172 * 0.001; +#X obj 46 83 t b b b; +#X obj 48 256 outlet; +#X obj 47 26 r init; +#X obj 49 217 pack 0 0 0 0.5; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 3 0; +#X connect 3 0 9 1; +#X connect 4 0 5 0; +#X connect 5 0 9 2; +#X connect 6 0 0 0; +#X connect 6 1 2 0; +#X connect 6 2 4 0; +#X connect 8 0 6 0; +#X connect 9 0 7 0; +#X restore 214 58 pd rand_color; +#X obj 231 85 t 1; +#X obj 99 228 circle 0.05; +#X connect 0 0 5 0; +#X connect 1 0 8 0; +#X connect 2 0 1 1; +#X connect 2 1 1 2; +#X connect 2 2 1 3; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 6 0 7 0; +#X connect 7 0 4 1; +#X restore 596 617 pd boid; +#X connect 0 0 1 0; +#X connect 1 0 0 0; +#X connect 2 0 4 0; +#X connect 3 0 43 0; +#X connect 4 0 10 0; +#X connect 4 0 43 0; +#X connect 5 0 15 0; +#X connect 5 0 15 2; +#X connect 6 0 15 1; +#X connect 8 0 5 0; +#X connect 8 1 6 0; +#X connect 10 0 8 0; +#X connect 11 0 10 1; +#X connect 13 0 12 0; +#X connect 13 0 11 0; +#X connect 14 0 12 0; +#X connect 15 0 16 0; +#X connect 15 0 17 0; +#X connect 16 0 7 0; +#X connect 43 0 49 0; +#X connect 49 0 18 0; +#X connect 49 1 19 0; +#X connect 49 2 20 0; +#X connect 49 3 21 0; +#X connect 49 4 22 0; +#X connect 49 5 23 0; +#X connect 49 6 24 0; +#X connect 49 7 25 0; +#X connect 49 8 26 0; +#X connect 49 9 27 0; +#X connect 49 10 28 0; +#X connect 49 11 29 0; +#X connect 49 12 30 0; +#X connect 49 13 31 0; +#X connect 49 14 32 0; +#X connect 49 15 33 0; +#X connect 49 16 34 0; +#X connect 49 17 35 0; +#X connect 49 18 36 0; +#X connect 49 19 37 0; +#X connect 49 20 38 0; +#X connect 49 21 39 0; +#X connect 49 22 40 0; +#X connect 49 23 41 0; +#X connect 49 24 42 0; +#X connect 49 25 44 0; +#X connect 49 26 45 0; +#X connect 49 27 46 0; +#X connect 49 28 47 0; +#X connect 49 29 48 0; +#X connect 49 30 50 0; +#X connect 49 31 51 0; +#X connect 49 32 52 0; +#X connect 49 33 53 0; +#X connect 49 34 54 0; +#X connect 49 35 55 0; +#X connect 49 36 56 0; +#X connect 49 37 57 0; +#X connect 49 38 58 0; +#X connect 49 39 59 0; +#X restore 57 430 pd gem_example; +#X msg 266 592 flyrect \$1 \$2 \$3 \$4 \$5 \$6; +#X text 392 575 bounding box (walls) in which to fly (l/t/r/b/f/b) +; +#X text 389 614 point to which boids are attracted (x/y/z); +#X obj 266 574 pack 0 0 0 0 0 0; +#X floatatom 423 556 5 0 0 0 - - -; +#X floatatom 462 556 5 0 0 0 - - -; +#X obj -150 488 print boids3d; +#X msg 266 652 attractpt \$1 \$2 \$3; +#X obj 266 632 pack 0 0 0; +#X floatatom 345 615 5 0 0 0 - - -; +#X text -190 105 float/2d/3d adaptation 08/2005 by a. sier / jasch +; +#N canvas 754 114 178 480 init 0; +#X obj 34 21 loadbang; +#X obj 94 21 r reset; +#X msg 15 78 \; neighbors 4; +#X msg 15 168 \; center 1; +#X msg 15 228 \; match 1; +#X msg 15 318 \; edgedist 1; +#X msg 15 348 \; speed 3; +#X obj 16 49 b; +#X obj 17 21 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 15 258 \; avoid 2; +#X msg 15 288 \; repel 2; +#X msg 15 378 \; inertia 8; +#X msg 15 138 \; minspeed 1; +#X msg 15 108 \; maxspeed 3; +#X msg 15 198 \; attract 3; +#X msg 15 408 \; accel 2; +#X msg 15 438 \; prefdist 1.5; +#X connect 0 0 7 0; +#X connect 1 0 7 0; +#X connect 7 0 2 0; +#X connect 7 0 13 0; +#X connect 7 0 12 0; +#X connect 7 0 3 0; +#X connect 7 0 14 0; +#X connect 7 0 4 0; +#X connect 7 0 9 0; +#X connect 7 0 10 0; +#X connect 7 0 6 0; +#X connect 7 0 11 0; +#X connect 7 0 15 0; +#X connect 7 0 16 0; +#X connect 8 0 7 0; +#X restore 57 411 pd init; +#N canvas 67 162 494 344 META 0; +#X text 12 165 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan +Wilkes for Pd version 0.42.; +#X text 12 145 AUTHOR Eric L. Singer; +#X text 12 5 KEYWORDS control; +#X text 12 45 DESCRIPTION bird flight and animal flock simulator; +#X text 12 65 INLET_0 bang mode dump reset number neighbors maxspeed +minspeed center attract match avoid repel edgedist speed inertia accel +prefdist flyrect attractpt; +#X text 12 105 OUTLET_0 list; +#X text 12 125 OUTLET_1 list; +#X text 12 25 LICENSE GPL v2; +#X restore 710 674 pd META; +#X obj -151 438 boids3d 16 0; +#X obj 604 10 import jasch_lib; +#X text -191 208 Boids takes an integer argument which is the number +of boids. Each time Boids receives a bang \, it calculates and outputs +the new positions of the boids. The output consists of the coordinates +for each boid \, the number and type depending on the mode.; +#X connect 0 0 48 0; +#X connect 1 0 47 0; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 47 0; +#X connect 5 0 6 0; +#X connect 6 0 47 0; +#X connect 7 0 8 0; +#X connect 8 0 47 0; +#X connect 9 0 10 0; +#X connect 10 0 47 0; +#X connect 11 0 12 0; +#X connect 12 0 47 0; +#X connect 13 0 14 0; +#X connect 14 0 47 0; +#X connect 15 0 81 0; +#X connect 16 0 17 0; +#X connect 17 0 47 0; +#X connect 18 0 19 0; +#X connect 19 0 47 0; +#X connect 20 0 21 0; +#X connect 21 0 47 0; +#X connect 22 0 23 0; +#X connect 23 0 47 0; +#X connect 24 0 25 0; +#X connect 25 0 47 0; +#X connect 26 0 27 0; +#X connect 27 0 47 0; +#X connect 28 0 48 0; +#X connect 35 0 71 0; +#X connect 36 0 71 1; +#X connect 37 0 71 2; +#X connect 38 0 71 3; +#X connect 39 0 76 0; +#X connect 40 0 76 1; +#X connect 41 0 42 0; +#X connect 42 0 47 0; +#X connect 44 0 45 0; +#X connect 45 0 48 0; +#X connect 66 0 81 0; +#X connect 68 0 47 0; +#X connect 71 0 68 0; +#X connect 72 0 71 4; +#X connect 73 0 71 5; +#X connect 75 0 47 0; +#X connect 76 0 75 0; +#X connect 77 0 76 2; +#X connect 81 0 74 0; +#X connect 81 1 64 0; diff --git a/boids3d.c b/boids3d.c new file mode 100644 index 0000000..f8dd975 --- /dev/null +++ b/boids3d.c @@ -0,0 +1,956 @@ +/* + + boids3d 2005 - 2006 a.sier / jasch + adapted from boids by eric singer © 1995-2003 eric l. singer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "m_pd.h" +#include +#include + +// constants +#define kAssistInlet 1 +#define kAssistOutlet 2 +#define kMaxLong 0xFFFFFFFF +#define kMaxNeighbors 4 + +// util +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define CLIP(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x) + +// initial flight parameters +const short kNumBoids = 12; // number of boids +const short kNumNeighbors = 2; // must be <= kMaxNeighbors +const double kMinSpeed = 0.15; // boids' minimum speed +const double kMaxSpeed = 0.25; // boids' maximum speed +const double kCenterWeight = 0.25; // flock centering +const double kAttractWeight = 0.300;// attraction point seeking +const double kMatchWeight = 0.100;// neighbors velocity matching +const double kAvoidWeight = 0.10; // neighbors avoidance +const double kWallsWeight = 0.500;// wall avoidance [210] +const double kEdgeDist = 0.5; // vision distance to avoid wall edges [5] +const double kSpeedupFactor = 0.100;// alter animation speed +const double kInertiaFactor = 0.20; // willingness to change speed & direction +const double kAccelFactor = 0.100;// neighbor avoidance accelerate or decelerate rate +const double kPrefDist = 0.25; // preferred distance from neighbors +const double kFlyRectTop = 1.0; // fly rect boundaries +const double kFlyRectLeft = -1.0; +const double kFlyRectBottom = -1.0; +const double kFlyRectRight = 1.0; +const double kFlyRectFront = 1.0; +const double kFlyRectBack = -1.0; + + +// typedefs +typedef struct Velocity { + double x; + double y; + double z; +} Velocity; + +typedef struct Point3d { + double x; + double y; + double z; +} Point3d; + +typedef struct Box3D { + double left, right; + double top, bottom; + double front, back; +} Box3D; + +typedef struct _Boid { + Point3d oldPos; + Point3d newPos; + Velocity oldDir; + Velocity newDir; + double speed; + short neighbor[kMaxNeighbors]; + double neighborDistSqr[kMaxNeighbors]; +} t_one_boid, *BoidPtr; + +typedef struct _FlockObject { + t_object ob; + void *out1, *out2; + short mode; + long numBoids; + long numNeighbors; + Box3D flyRect; + double minSpeed; + double maxSpeed; + double centerWeight; + double attractWeight; + double matchWeight; + double avoidWeight; + double wallsWeight; + double edgeDist; + double speedupFactor; + double inertiaFactor; + double accelFactor; + double prefDist; + double prefDistSqr; + Point3d centerPt; + Point3d attractPt; + BoidPtr boid; + double d2r, r2d; +} t_boids, *FlockPtr; + + +t_symbol *ps_nothing; + +void *boids3d_class; +void *Flock_new(t_symbol *s, long argc, t_atom *argv); +void Flock_free(t_boids *x); +void Flock_bang(t_boids *x); +void Flock_dump(t_boids *x); +void Flock_mode(t_boids *x, t_float arg); +void Flock_numNeighbors(t_boids *x, t_float arg); +void Flock_numBoids(t_boids *x, t_float arg); +void Flock_minSpeed(t_boids *x, t_float arg); +void Flock_maxSpeed(t_boids *x, t_float arg); +void Flock_centerWeight(t_boids *x, t_float arg); +void Flock_attractWeight(t_boids *x, t_float arg); +void Flock_matchWeight(t_boids *x, t_float arg); +void Flock_avoidWeight(t_boids *x, t_float arg); +void Flock_wallsWeight(t_boids *x, t_float arg); +void Flock_edgeDist(t_boids *x, t_float arg); +void Flock_speedupFactor(t_boids *x, t_float arg); +void Flock_inertiaFactor(t_boids *x, t_float arg); +void Flock_accelFactor(t_boids *x, t_float arg); +void Flock_prefDist(t_boids *x, t_float arg); +void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv); +void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv); +void Flock_reset(t_boids *x); +void Flock_resetBoids(t_boids *x); +void InitFlock(t_boids *x); +void FlightStep(t_boids *x); +Point3d FindFlockCenter(t_boids *x); +float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel); +Velocity SeekPoint(t_boids *x, short theBoid, Point3d seekPt); +Velocity AvoidWalls(t_boids *x, short theBoid); +int InFront(BoidPtr theBoid, BoidPtr neighbor); +void NormalizeVelocity(Velocity *direction); +double RandomInt(double minRange, double maxRange); +double DistSqrToPt(Point3d firstPoint, Point3d secondPoint); + +void boids3d_setup(void) +{ + boids3d_class = class_new(gensym("boids3d"), (t_newmethod)Flock_new, + (t_method)Flock_free, sizeof(t_boids), 0, A_GIMME, 0); + class_addfloat(boids3d_class, (t_method) Flock_numBoids); + class_addbang(boids3d_class, (t_method) Flock_bang); + class_addmethod(boids3d_class, (t_method) Flock_numNeighbors, gensym("neighbors"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_numBoids, gensym("number"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_mode, gensym("mode"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_minSpeed, gensym("minspeed"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_maxSpeed, gensym("maxspeed"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_centerWeight, gensym("center"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_attractWeight, gensym("attract"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_matchWeight, gensym("match"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_avoidWeight, gensym("avoid"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_wallsWeight, gensym("repel"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_edgeDist, gensym("edgedist"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_speedupFactor, gensym("speed"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_inertiaFactor, gensym("inertia"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_accelFactor, gensym("accel"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_prefDist, gensym("prefdist"), A_FLOAT, 0); + class_addmethod(boids3d_class, (t_method) Flock_flyRect, gensym("flyrect"), A_GIMME, 0); + class_addmethod(boids3d_class, (t_method) Flock_attractPt, gensym("attractpt"), A_GIMME, 0); + class_addmethod(boids3d_class, (t_method) Flock_resetBoids, gensym("reset"), 0); + class_addmethod(boids3d_class, (t_method) Flock_reset, gensym("init"), 0); + class_addmethod(boids3d_class, (t_method) Flock_dump, gensym("dump"), 0); + + post("boids3d 2005-2006 a.sier / jasch © 1995-2003 eric l. singer "__DATE__" "__TIME__); + ps_nothing = gensym(""); +} + + +void *Flock_new(t_symbol *s, long argc, t_atom *argv) +{ + t_boids *x = (t_boids *)pd_new(boids3d_class); + x->out1 = outlet_new(&x->ob, NULL); + x->out2 = outlet_new(&x->ob, NULL); + + x->numBoids = 16; + if((argc >= 1) && (argv[0].a_type == A_FLOAT)){ + x->numBoids = argv[0].a_w.w_float; + } + x->boid = (t_one_boid *)malloc(sizeof(t_one_boid) * x->numBoids); + + InitFlock(x); + + x->mode = 0; + if((argc >= 2) && (argv[1].a_type == A_FLOAT)){ + x->mode = (short)(CLIP(argv[1].a_w.w_float, 0, 2)); + } + + x->d2r = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068/180.0; + x->r2d = 180.0/3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068; + + return(x); +} + +void Flock_free(t_boids *x) +{ + free(x->boid); +} + +void Flock_bang(t_boids *x) +{ + short i; + t_atom outlist[10]; + t_atom *out; + + double tempNew_x, tempNew_y, tempNew_z; + double tempOld_x, tempOld_y, tempOld_z; + double delta_x, delta_y, delta_z; + double azi, ele, speed; + + out = outlist; + + FlightStep(x); + + + switch(x->mode) { // newpos + case 0: + for (i = 0; i < x->numBoids; i++){ + SETFLOAT(out+0, i); + SETFLOAT(out+1, x->boid[i].newPos.x); + SETFLOAT(out+2, x->boid[i].newPos.y); + SETFLOAT(out+3, x->boid[i].newPos.z); + outlet_list(x->out1, 0L, 4, out); + } + break; + case 1: //newpos + oldpos + for (i = 0; i < x->numBoids; i++){ + SETFLOAT(out+0, i); + SETFLOAT(out+1, x->boid[i].newPos.x); + SETFLOAT(out+2, x->boid[i].newPos.y); + SETFLOAT(out+3, x->boid[i].newPos.z); + SETFLOAT(out+4, x->boid[i].oldPos.x); + SETFLOAT(out+5, x->boid[i].oldPos.y); + SETFLOAT(out+6, x->boid[i].oldPos.z); + outlet_list(x->out1, 0L, 7, out); + } + break; + case 2: + for (i = 0; i < x->numBoids; i++){ + tempNew_x = x->boid[i].newPos.x; + tempNew_y = x->boid[i].newPos.y; + tempNew_z = x->boid[i].newPos.z; + tempOld_x = x->boid[i].oldPos.x; + tempOld_y = x->boid[i].oldPos.y; + tempOld_z = x->boid[i].oldPos.z; + delta_x = tempNew_x - tempOld_x; + delta_y = tempNew_y - tempOld_y; + delta_z = tempNew_z - tempOld_z; + azi = atan2(delta_y, delta_x) * x->r2d; + ele = atan2(delta_y, delta_x) * x->r2d; + speed = sqrt(delta_x * delta_x + delta_y * delta_y + delta_z * delta_z); + SETFLOAT(out+0, i); + SETFLOAT(out+1, tempNew_x); + SETFLOAT(out+2, tempNew_y); + SETFLOAT(out+3, tempNew_z); + SETFLOAT(out+4, tempOld_x); + SETFLOAT(out+5, tempOld_y); + SETFLOAT(out+6, tempOld_z); + SETFLOAT(out+7, speed); + SETFLOAT(out+8, azi); + SETFLOAT(out+9, ele); + outlet_list(x->out1, 0L, 10, out); + } + break; + } +} + +void Flock_dump(t_boids *x) +{ + t_atom outList[6]; + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->numNeighbors; + outlet_anything(x->out2, gensym("neighbors"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->minSpeed; + outlet_anything(x->out2, gensym("minspeed"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->maxSpeed; + outlet_anything(x->out2, gensym("maxspeed"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->centerWeight; + outlet_anything(x->out2, gensym("center"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->attractWeight; + outlet_anything(x->out2, gensym("attract"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->matchWeight; + outlet_anything(x->out2, gensym("match"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->avoidWeight; + outlet_anything(x->out2, gensym("avoid"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->wallsWeight; + outlet_anything(x->out2, gensym("repel"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->edgeDist; + outlet_anything(x->out2, gensym("edgedist"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->speedupFactor; + outlet_anything(x->out2, gensym("speed"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->inertiaFactor; + outlet_anything(x->out2, gensym("inertia"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->accelFactor; + outlet_anything(x->out2, gensym("accel"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->prefDist; + outlet_anything(x->out2, gensym("prefdist"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->flyRect.left; + outList[1].a_type = A_FLOAT; + outList[1].a_w.w_float = x->flyRect.top; + outList[2].a_type = A_FLOAT; + outList[2].a_w.w_float = x->flyRect.right; + outList[3].a_type = A_FLOAT; + outList[3].a_w.w_float = x->flyRect.bottom; + outList[4].a_type = A_FLOAT; + outList[4].a_w.w_float = x->flyRect.front; + outList[5].a_type = A_FLOAT; + outList[5].a_w.w_float = x->flyRect.back; + outlet_anything(x->out2, gensym("flyrect"), 6, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->attractPt.x; + outList[1].a_type = A_FLOAT; + outList[1].a_w.w_float = x->attractPt.y; + outList[2].a_type = A_FLOAT; + outList[2].a_w.w_float = x->attractPt.z; + outlet_anything(x->out2, gensym("attractpt"), 3, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->mode; + outlet_anything(x->out2, gensym("mode"), 1, outList); + + outList[0].a_type = A_FLOAT; + outList[0].a_w.w_float = x->numBoids; + outlet_anything(x->out2, gensym("number"), 1, outList); +} + + +void Flock_mode(t_boids *x, t_float arg) +{ + long m = (long)arg; + x->mode = CLIP(m, 0, 2); +} + +void Flock_numNeighbors(t_boids *x, t_float arg) +{ + x->numNeighbors = (long)arg; +} + +void Flock_numBoids(t_boids *x, t_float arg) +{ + x->boid = (t_one_boid *)realloc(x->boid, sizeof(t_one_boid) * (long)arg); + x->numBoids = (long)arg; + Flock_resetBoids(x); +} + +void Flock_minSpeed(t_boids *x, t_float arg) +{ + x->minSpeed = MAX(arg, 0.000001); +} + +void Flock_maxSpeed(t_boids *x, t_float arg) +{ + x->maxSpeed = (double)arg; +} + +void Flock_centerWeight(t_boids *x, t_float arg) +{ + x->centerWeight = (double)arg; +} + +void Flock_attractWeight(t_boids *x, t_float arg) +{ + x->attractWeight = (double)arg; +} + +void Flock_matchWeight(t_boids *x, t_float arg) +{ + x->matchWeight = (double)arg; +} + +void Flock_avoidWeight(t_boids *x, t_float arg) +{ + x->avoidWeight = (double)arg; +} + +void Flock_wallsWeight(t_boids *x, t_float arg) +{ + x->wallsWeight = (double)arg; +} + +void Flock_edgeDist(t_boids *x, t_float arg) +{ + x->edgeDist = (double)arg; +} + +void Flock_speedupFactor(t_boids *x, t_float arg) +{ + x->speedupFactor = (double)arg; +} + +void Flock_inertiaFactor(t_boids *x, t_float arg) +{ + if(arg == 0){ + x->inertiaFactor = 0.000001; + }else{ + x->inertiaFactor = (double)arg; + } +} + +void Flock_accelFactor(t_boids *x, t_float arg) +{ + x->accelFactor = (double)arg; +} + +void Flock_prefDist(t_boids *x, t_float arg) +{ + x->prefDist = (double)arg; +} + +void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv) +{ + double temp[6]; + short i; + if(argc == 6){ + for(i = 0; i < 6; i++) { + if(argv[i].a_type == A_FLOAT) { + temp[i] = (double)argv[i].a_w.w_float; + } + } + x->flyRect.left = temp[0]; + x->flyRect.top = temp[1]; + x->flyRect.right = temp[2]; + x->flyRect.bottom = temp[3]; + x->flyRect.front = temp[4]; + x->flyRect.back = temp[5]; + }else{ + error("boids3d: flyrect needs 6 values"); + } +} + +void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv) +{ + double temp[3]; + short i; + if(argc == 3){ + for(i = 0; i < 3 ; i++) { + if(argv[i].a_type == A_FLOAT) { + temp[i] = (double)argv[i].a_w.w_float; + } + } + x->attractPt.x = temp[0]; + x->attractPt.y = temp[1]; + x->attractPt.z = temp[2]; + }else{ + error("boids3d: attractPt needs 3 values"); + } +} + +void Flock_reset(t_boids *x) +{ + InitFlock(x); +} + +void Flock_resetBoids(t_boids *x) +{ + long i, j; + double rndAngle; + + for (i = 0; i < x->numBoids; i++) { // init everything to 0.0 + x->boid[i].oldPos.x = 0.0; + x->boid[i].oldPos.y = 0.0; + x->boid[i].oldPos.z = 0.0; + + x->boid[i].newPos.x = 0.0; + x->boid[i].newPos.y = 0.0; + x->boid[i].newPos.z = 0.0; + + x->boid[i].oldDir.x = 0.0; + x->boid[i].oldDir.y = 0.0; + x->boid[i].oldDir.z = 0.0; + + x->boid[i].newDir.x = 0.0; + x->boid[i].newDir.y = 0.0; + x->boid[i].newDir.z = 0.0; + + x->boid[i].speed = 0.0; + + for(j=0; jboid[i].neighbor[j] = 0; + x->boid[i].neighborDistSqr[j] = 0.0; + } + } + for (i = 0; i < x->numBoids; i++) { // set the initial locations and velocities of the boids + x->boid[i].newPos.x = x->boid[i].oldPos.x = RandomInt(x->flyRect.right,x->flyRect.left); // set random location within flyRect + x->boid[i].newPos.y = x->boid[i].oldPos.y = RandomInt(x->flyRect.bottom, x->flyRect.top); + x->boid[i].newPos.z = x->boid[i].oldPos.z = RandomInt(x->flyRect.back, x->flyRect.front); + rndAngle = RandomInt(0, 360) * x->d2r; // set velocity from random angle + x->boid[i].newDir.x = sin(rndAngle); + x->boid[i].newDir.y = cos(rndAngle); + x->boid[i].newDir.z = (cos(rndAngle) + sin(rndAngle)) * 0.5; + x->boid[i].speed = (kMaxSpeed + kMinSpeed) * 0.5; + } +} + +void InitFlock(t_boids *x) +{ + x->numNeighbors = kNumNeighbors; + x->minSpeed = kMinSpeed; + x->maxSpeed = kMaxSpeed; + x->centerWeight = kCenterWeight; + x->attractWeight = kAttractWeight; + x->matchWeight = kMatchWeight; + x->avoidWeight = kAvoidWeight; + x->wallsWeight = kWallsWeight; + x->edgeDist = kEdgeDist; + x->speedupFactor = kSpeedupFactor; + x->inertiaFactor = kInertiaFactor; + x->accelFactor = kAccelFactor; + x->prefDist = kPrefDist; + x->prefDistSqr = kPrefDist * kPrefDist; + x->flyRect.top = kFlyRectTop; + x->flyRect.left = kFlyRectLeft; + x->flyRect.bottom = kFlyRectBottom; + x->flyRect.right = kFlyRectRight; + x->flyRect.front = kFlyRectFront; + x->flyRect.back = kFlyRectBack; + x->attractPt.x = (kFlyRectLeft + kFlyRectRight) * 0.5; + x->attractPt.y = (kFlyRectTop + kFlyRectBottom) * 0.5; + x->attractPt.z = (kFlyRectFront + kFlyRectBack) * 0.5; + Flock_resetBoids(x); +} + +void FlightStep(t_boids *x) +{ + Velocity goCenterVel; + Velocity goAttractVel; + Velocity matchNeighborVel; + Velocity avoidWallsVel; + Velocity avoidNeighborVel; + float avoidNeighborSpeed; + const Velocity zeroVel = {0.0, 0.0, 0.0}; + short i; + + x->centerPt = FindFlockCenter(x); + for (i = 0; i < x->numBoids; i++) { // save position and velocity + x->boid[i].oldPos.x = x->boid[i].newPos.x; + x->boid[i].oldPos.y = x->boid[i].newPos.y; + x->boid[i].oldPos.z = x->boid[i].newPos.z; + + x->boid[i].oldDir.x = x->boid[i].newDir.x; + x->boid[i].oldDir.y = x->boid[i].newDir.y; + x->boid[i].oldDir.z = x->boid[i].newDir.z; + } + for (i = 0; i < x->numBoids; i++) { + if (x->numNeighbors > 0) { // get all velocity components + avoidNeighborSpeed = MatchAndAvoidNeighbors(x, i,&matchNeighborVel, &avoidNeighborVel); + } else { + matchNeighborVel = zeroVel; + avoidNeighborVel = zeroVel; + avoidNeighborSpeed = 0; + } + goCenterVel = SeekPoint(x, i, x->centerPt); + goAttractVel = SeekPoint(x, i, x->attractPt); + avoidWallsVel = AvoidWalls(x, i); + + // compute resultant velocity using weights and inertia + x->boid[i].newDir.x = x->inertiaFactor * (x->boid[i].oldDir.x) + + (x->centerWeight * goCenterVel.x + + x->attractWeight * goAttractVel.x + + x->matchWeight * matchNeighborVel.x + + x->avoidWeight * avoidNeighborVel.x + + x->wallsWeight * avoidWallsVel.x) / x->inertiaFactor; + x->boid[i].newDir.y = x->inertiaFactor * (x->boid[i].oldDir.y) + + (x->centerWeight * goCenterVel.y + + x->attractWeight * goAttractVel.y + + x->matchWeight * matchNeighborVel.y + + x->avoidWeight * avoidNeighborVel.y + + x->wallsWeight * avoidWallsVel.y) / x->inertiaFactor; + x->boid[i].newDir.z = x->inertiaFactor * (x->boid[i].oldDir.z) + + (x->centerWeight * goCenterVel.z + + x->attractWeight * goAttractVel.z + + x->matchWeight * matchNeighborVel.z + + x->avoidWeight * avoidNeighborVel.z + + x->wallsWeight * avoidWallsVel.z) / x->inertiaFactor; + NormalizeVelocity(&(x->boid[i].newDir)); // normalize velocity so its length is unity + + // set to avoidNeighborSpeed bounded by minSpeed and maxSpeed + if ((avoidNeighborSpeed >= x->minSpeed) && + (avoidNeighborSpeed <= x->maxSpeed)) + x->boid[i].speed = avoidNeighborSpeed; + else if (avoidNeighborSpeed > x->maxSpeed) + x->boid[i].speed = x->maxSpeed; + else + x->boid[i].speed = x->minSpeed; + + // calculate new position, applying speedupFactor + x->boid[i].newPos.x += x->boid[i].newDir.x * x->boid[i].speed * (x->speedupFactor / 100.0); + x->boid[i].newPos.y += x->boid[i].newDir.y * x->boid[i].speed * (x->speedupFactor / 100.0); + x->boid[i].newPos.z += x->boid[i].newDir.z * x->boid[i].speed * (x->speedupFactor / 100.0); + + } +} + +Point3d FindFlockCenter(t_boids *x) +{ + double totalH = 0, totalV = 0, totalD = 0; + Point3d centerPoint; + register short i; + + for (i = 0 ; i < x->numBoids; i++) + { + totalH += x->boid[i].oldPos.x; + totalV += x->boid[i].oldPos.y; + totalD += x->boid[i].oldPos.z; + } + centerPoint.x = (double) (totalH / x->numBoids); + centerPoint.y = (double) (totalV / x->numBoids); + centerPoint.z = (double) (totalD / x->numBoids); + + return(centerPoint); +} + +float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel) +{ + short i, j, neighbor; + double distSqr; + double dist, distH, distV,distD; + double tempSpeed; + short numClose = 0; + Velocity totalVel = {0.0, 0.0, 0.0}; + + /**********************/ + /* Find the neighbors */ + /**********************/ + + /* special case of one neighbor */ + if (x->numNeighbors == 1) { + x->boid[theBoid].neighborDistSqr[0] = kMaxLong; + + for (i = 0; i < x->numBoids; i++) { + if (i != theBoid) { + distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); + + /* if this one is closer than the closest so far, then remember it */ + if (x->boid[theBoid].neighborDistSqr[0] > distSqr) { + x->boid[theBoid].neighborDistSqr[0] = distSqr; + x->boid[theBoid].neighbor[0] = i; + } + } + } + } + /* more than one neighbor */ + else { + for (j = 0; j < x->numNeighbors; j++) + x->boid[theBoid].neighborDistSqr[j] = kMaxLong; + + for (i = 0 ; i < x->numBoids; i++) { + /* if this one is not me... */ + if (i != theBoid) { + distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); + + /* if distSqr is less than the distance at the bottom of the array, sort into array */ + if (distSqr < x->boid[theBoid].neighborDistSqr[x->numNeighbors-1]) { + j = x->numNeighbors - 1; + + /* sort distSqr in to keep array in size order, smallest first */ + while ((distSqr < x->boid[theBoid].neighborDistSqr[j-1]) && (j > 0)) { + x->boid[theBoid].neighborDistSqr[j] = x->boid[theBoid].neighborDistSqr[j - 1]; + x->boid[theBoid].neighbor[j] = x->boid[theBoid].neighbor[j - 1]; + j--; + } + x->boid[theBoid].neighborDistSqr[j] = distSqr; + x->boid[theBoid].neighbor[j] = i; + } + } + } + } + + /*********************************/ + /* Match and avoid the neighbors */ + /*********************************/ + + matchNeighborVel->x = 0; + matchNeighborVel->y = 0; + matchNeighborVel->z = 0; + + // set tempSpeed to old speed + tempSpeed = x->boid[theBoid].speed; + + for (i = 0; i < x->numNeighbors; i++) { + neighbor = x->boid[theBoid].neighbor[i]; + + // calculate matchNeighborVel by averaging the neighbor velocities + matchNeighborVel->x += x->boid[neighbor].oldDir.x; + matchNeighborVel->y += x->boid[neighbor].oldDir.y; + matchNeighborVel->z += x->boid[neighbor].oldDir.z; + + // if distance is less than preferred distance, then neighbor influences boid + distSqr = x->boid[theBoid].neighborDistSqr[i]; + if (distSqr < x->prefDistSqr) { + dist = sqrt(distSqr); + + distH = x->boid[neighbor].oldPos.x - x->boid[theBoid].oldPos.x; + distV = x->boid[neighbor].oldPos.y - x->boid[theBoid].oldPos.y; + distD = x->boid[neighbor].oldPos.z - x->boid[theBoid].oldPos.z; + + if(dist == 0.0) dist = 0.0000001; + totalVel.x = totalVel.x - distH - (distH * ((float) x->prefDist / (dist))); + totalVel.y = totalVel.y - distV - (distV * ((float) x->prefDist / (dist))); + totalVel.z = totalVel.z - distD - (distV * ((float) x->prefDist / (dist))); + + numClose++; + } + if (InFront(&(x->boid[theBoid]), &(x->boid[neighbor]))) { // adjust speed + if (distSqr < x->prefDistSqr) + tempSpeed /= (x->accelFactor / 100.0); + else + tempSpeed *= (x->accelFactor / 100.0); + } + else { + if (distSqr < x->prefDistSqr) + tempSpeed *= (x->accelFactor / 100.0); + else + tempSpeed /= (x->accelFactor / 100.0); + } + } + if (numClose) { + avoidNeighborVel->x = totalVel.x / numClose; + avoidNeighborVel->y = totalVel.y / numClose; + avoidNeighborVel->z = totalVel.z / numClose; + NormalizeVelocity(matchNeighborVel); + } + else { + avoidNeighborVel->x = 0; + avoidNeighborVel->y = 0; + avoidNeighborVel->z = 0; + } + return(tempSpeed); +} + + +Velocity SeekPoint(t_boids *x, short theBoid, Point3d seekPt) +{ + Velocity tempDir; + tempDir.x = seekPt.x - x->boid[theBoid].oldPos.x; + tempDir.y = seekPt.y - x->boid[theBoid].oldPos.y; + tempDir.z = seekPt.z - x->boid[theBoid].oldPos.z; + NormalizeVelocity(&tempDir); + return(tempDir); +} + + +Velocity AvoidWalls(t_boids *x, short theBoid) +{ + Point3d testPoint; + Velocity tempVel = {0.0, 0.0, 0.0}; + + /* calculate test point in front of the nose of the boid */ + /* distance depends on the boid's speed and the avoid edge constant */ + testPoint.x = x->boid[theBoid].oldPos.x + x->boid[theBoid].oldDir.x * x->boid[theBoid].speed * x->edgeDist; + testPoint.y = x->boid[theBoid].oldPos.y + x->boid[theBoid].oldDir.y * x->boid[theBoid].speed * x->edgeDist; + testPoint.z = x->boid[theBoid].oldPos.z + x->boid[theBoid].oldDir.z * x->boid[theBoid].speed * x->edgeDist; + + /* if test point is out of the left (right) side of x->flyRect, */ + /* return a positive (negative) horizontal velocity component */ + if (testPoint.x < x->flyRect.left) + tempVel.x = fabs(x->boid[theBoid].oldDir.x); + else if (testPoint.x > x->flyRect.right) + tempVel.x = - fabs(x->boid[theBoid].oldDir.x); + + /* same with top and bottom */ + if (testPoint.y < x->flyRect.top) + tempVel.y = fabs(x->boid[theBoid].oldDir.y); + else if (testPoint.y > x->flyRect.bottom) + tempVel.y = - fabs(x->boid[theBoid].oldDir.y); + + /* same with front and back */ + if (testPoint.z < x->flyRect.front) + tempVel.z = fabs(x->boid[theBoid].oldDir.z); + else if (testPoint.z > x->flyRect.back) + tempVel.z = - fabs(x->boid[theBoid].oldDir.z); + + return(tempVel); +} + + +int InFront(BoidPtr theBoid, BoidPtr neighbor) +{ + float grad, intercept; + int result; + +/* + +Find the gradient and y-intercept of a line passing through theBoid's oldPos +perpendicular to its direction of motion. Another boid is in front of theBoid +if it is to the right or left of this linedepending on whether theBoid is moving +right or left. However, if theBoid is travelling vertically then just compare +their vertical coordinates. + +*/ + // xy plane + + // if theBoid is not travelling vertically... + if (theBoid->oldDir.x != 0) { + // calculate gradient of a line _perpendicular_ to its direction (hence the minus) + grad = -theBoid->oldDir.y / theBoid->oldDir.x; + + // calculate where this line hits the y axis (from y = mx + c) + intercept = theBoid->oldPos.y - (grad * theBoid->oldPos.x); + + /* compare the horizontal position of the neighbor boid with */ + /* the point on the line that has its vertical coordinate */ + if (neighbor->oldPos.x >= ((neighbor->oldPos.y - intercept) / grad)) { + /* return true if the first boid's horizontal movement is +ve */ + result = (theBoid->oldDir.x > 0); + + if (result==0) return 0; + else goto next; + + } else { + /* return true if the first boid's horizontal movement is +ve */ + result = (theBoid->oldDir.x < 0); + if (result==0) return 0; + else goto next; + } + } + /* else theBoid is travelling vertically, so just compare vertical coordinates */ + else if (theBoid->oldDir.y > 0) { + result = (neighbor->oldPos.y > theBoid->oldPos.y); + if (result==0){ + return 0; + }else{ + goto next; + } + }else{ + result = (neighbor->oldPos.y < theBoid->oldPos.y); + if (result==0){ + return 0; + } else { + goto next; + } + } +next: + // yz plane + + // if theBoid is not travelling vertically... + if (theBoid->oldDir.y != 0) { + // calculate gradient of a line _perpendicular_ to its direction (hence the minus) + grad = -theBoid->oldDir.z / theBoid->oldDir.y; + + // calculate where this line hits the y axis (from y = mx + c) + intercept = theBoid->oldPos.z - (grad * theBoid->oldPos.y); + + // compare the horizontal position of the neighbor boid with + // the point on the line that has its vertical coordinate + if (neighbor->oldPos.y >= ((neighbor->oldPos.z - intercept) / grad)) { + // return true if the first boid's horizontal movement is +ve + result = (theBoid->oldDir.y > 0); + if (result==0){ + return 0; + }else{ + goto next2; + } + } else { + // return true if the first boid's horizontal movement is +ve + result = (theBoid->oldDir.y < 0); + if (result==0){ + return 0; + }else{ + goto next2; + } + } + } + // else theBoid is travelling vertically, so just compare vertical coordinates + else if (theBoid->oldDir.z > 0) { + result = (neighbor->oldPos.z > theBoid->oldPos.z); + if (result==0){ + return 0; + }else{ + goto next2; + } + }else{ + result = (neighbor->oldPos.z < theBoid->oldPos.z); + if (result==0){ + return 0; + }else{ + goto next2; + } + } +next2: + return 1; +} + +void NormalizeVelocity(Velocity *direction) +{ + float my_hypot; + + my_hypot = sqrt(direction->x * direction->x + direction->y * direction->y + direction->z * direction->z ); + + if (my_hypot != 0.0) { + direction->x = direction->x / my_hypot; + direction->y = direction->y / my_hypot; + direction->z = direction->z / my_hypot; + } +} + +double RandomInt(double minRange, double maxRange) +{ + unsigned short qdRdm; + double t, result; + + qdRdm = rand(); + t = (double)qdRdm / 65536.0; // now 0 <= t <= 1 + result = (t * (maxRange - minRange)) + minRange; + return(result); +} + +double DistSqrToPt(Point3d firstPoint, Point3d secondPoint) +{ + double a, b,c; + a = firstPoint.x - secondPoint.x; + b = firstPoint.y - secondPoint.y; + c = firstPoint.z - secondPoint.z; + return(a * a + b * b + c * c); +} \ No newline at end of file diff --git a/boids3d/boids3d-help.pd b/boids3d/boids3d-help.pd deleted file mode 100644 index 95acaf0..0000000 --- a/boids3d/boids3d-help.pd +++ /dev/null @@ -1,2101 +0,0 @@ -#N canvas 0 31 963 634 10; -#X declare -lib jasch_lib; -#X msg -99 601 dump; -#X msg 266 113 neighbors \$1; -#X floatatom 266 98 5 0 4 0 - neighbors -; -#X floatatom 266 133 5 0 0 0 - maxspeed -; -#X msg 266 148 maxspeed \$1; -#X floatatom 266 168 5 0 0 0 - minspeed -; -#X msg 266 183 minspeed \$1; -#X floatatom 266 203 5 0 0 0 - center -; -#X msg 266 218 center \$1; -#X floatatom 266 238 5 0 0 0 - attract -; -#X msg 266 253 attract \$1; -#X floatatom 266 273 5 0 0 0 - match -; -#X msg 266 288 match \$1; -#X floatatom 266 308 5 0 0 0 - avoid -; -#X msg 266 323 avoid \$1; -#X obj -125 411 r boidParam; -#X floatatom 266 343 5 0 0 0 - repel -; -#X msg 266 358 repel \$1; -#X floatatom 266 378 5 0 0 0 - edgedist -; -#X msg 266 393 edgedist \$1; -#X floatatom 266 413 5 0 0 0 - speed -; -#X msg 266 428 speed \$1; -#X floatatom 266 448 5 0 0 0 - inertia -; -#X msg 266 463 inertia \$1; -#X floatatom 266 483 5 0 0 0 - accel -; -#X msg 266 498 accel \$1; -#X floatatom 266 518 5 0 0 0 - prefdist -; -#X msg 266 533 prefdist \$1; -#X msg -99 620 reset; -#X text 357 148 maximum speed of speed range; -#X text 359 182 minimum speed of speed range; -#X text 356 217 strength of centering instinct; -#X text 358 428 overall speed; -#X text 359 499 speed of acceleration; -#X text 359 530 preferred distance from neighbors; -#X floatatom 267 556 5 0 0 0 - flyrect[0] -; -#X floatatom 306 556 5 0 0 0 - flyrect[1] -; -#X floatatom 345 556 5 0 0 0 - flyrect[2] -; -#X floatatom 384 556 5 0 0 0 - - -; -#X floatatom 266 615 5 0 0 0 - - -; -#X floatatom 306 615 5 0 0 0 - - -; -#X floatatom 266 63 5 0 0 0 - - -; -#X msg 266 78 number \$1; -#X text 357 76 number of boids; -#X floatatom -99 567 5 0 0 0 - - -; -#X msg -99 582 mode \$1; -#X text -35 582 output mode; -#X obj 266 676 s boidParam; -#X obj -99 641 s boidParam; -#X text -35 601 parameter dump; -#X text -36 621 reset boids randomly inside flyrect; -#X text 357 111 number of neighbors each boid consults when flocking -; -#X text 356 288 strength of neighbor speed matching instinct; -#X text 356 323 strength of neighbor avoidance instinct; -#X text 356 355 strength of wall avoidance instinct; -#X text 358 391 distance of vision for avoiding wall edges; -#X text 359 462 willingness to change speed and direction; -#X text 355 251 strength of attraction to 'attractpt'; -#X text -191 84 (c) 1995-98 Eric L. Singer (eric@ericsinger.com); -#X text -191 126 Based on Simon Fraser's implementation of Craig Reynolds' -Boids algorithm. Boids is free for non-commercial use; -#X text -191 159 Boids is a bird flight and animal flock simulator. -It is based on the same algorithm which was used in Jurassic Park for -the herding dinosaurs.; -#X text -190 282 The flight parameters can be changed with messages. -Use the 'dump' message to output a list of the current parameter settings. -; -#X text -190 328 For more information about the Boids algorithm \, -see Craig Reynolds' Web site at "http://reality.sgi.com/employees/craig/boids.html". -; -#X text -188 64 arguments: number of boids \, output -mode; -#X obj -72 460 print dump; -#X obj -203 9 cnv 15 800 48 empty empty boids3d 20 12 2 24 -228915 --66577 0; -#X obj -151 410 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 --1 -1; -#N canvas 241 22 783 706 gem_example 0; -#X msg 33 31 create; -#N canvas 494 140 629 324 gemwin 0; -#X obj 219 190 gemwin; -#X obj 66 194 outlet; -#X obj 67 10 inlet; -#X obj 67 41 route create; -#X msg 67 70 set destroy; -#X msg 157 70 set create; -#X msg 350 115 destroy \, reset; -#X msg 238 71 color 0 0 0.5; -#X msg 212 146 create \, 1 \, frame 30 \, color 1 1 1; -#X connect 2 0 3 0; -#X connect 3 0 4 0; -#X connect 3 0 8 0; -#X connect 3 1 5 0; -#X connect 3 1 6 0; -#X connect 4 0 1 0; -#X connect 5 0 1 0; -#X connect 6 0 0 0; -#X connect 7 0 0 0; -#X connect 8 0 0 0; -#X restore 33 51 pd gemwin; -#X obj 33 91 tgl 15 0 empty empty start_flocking_animation 20 6 1 10 --262144 -1 -1 0 1; -#X obj 204 135 r boidParam; -#X obj 33 112 metro 33; -#X floatatom 33 244 5 0 0 0 - - -; -#X floatatom 84 244 5 0 0 0 - - -; -#X obj 86 318 s boidParam; -#N canvas 0 22 466 316 orbit 0; -#X obj 103 82 counter 360; -#X floatatom 103 107 5 0 0 0 - - -; -#X obj 102 204 poltocar; -#X obj 134 169 expr $f1 * (3.141593/180.); -#X obj 103 134 t b f; -#X obj 103 45 inlet; -#X obj 152 254 outlet; -#X obj 96 254 outlet; -#X obj 102 170 1.5; -#X connect 0 0 1 0; -#X connect 1 0 4 0; -#X connect 2 0 6 0; -#X connect 2 1 7 0; -#X connect 3 0 2 1; -#X connect 4 0 8 0; -#X connect 4 1 3 0; -#X connect 5 0 0 0; -#X connect 8 0 2 0; -#X restore 33 222 pd orbit; -#X text 96 30 create/destroy OpenGl context; -#X obj 33 181 spigot; -#X obj 69 160 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 -; -#X obj 339 113 s init; -#X obj 358 84 loadbang; -#X obj 340 85 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X obj 33 267 pack 0 0 0; -#X msg 85 295 attractpt \$1 \$2 \$3; -#N canvas 0 22 414 375 center 0; -#X obj 101 37 gemhead; -#X obj 99 201 translateXYZ; -#X obj 124 166 unpack 0 0 0; -#X obj 147 94 inlet; -#X msg 240 193 draw line; -#X obj 252 106 loadbang; -#X obj 100 131 alpha; -#X obj 101 68 color 1 0.5 0 0.5; -#X obj 99 228 circle 0.1; -#X connect 0 0 7 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 8 0; -#X connect 5 0 4 0; -#X connect 6 0 1 0; -#X connect 7 0 6 0; -#X restore 32 342 pd center; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 206 227 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 216 237 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 226 247 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 236 257 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 246 267 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 256 277 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 266 287 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 276 297 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 286 307 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 296 317 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 306 327 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 316 337 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 326 347 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 336 357 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 346 367 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 356 377 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 366 387 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 376 397 pd boid; -#N canvas 213 30 510 360 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 386 407 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 396 417 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 406 427 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 416 437 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 426 447 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 436 457 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 446 467 pd boid; -#X obj 205 163 boids3d 40; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 456 477 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 466 487 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 476 497 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 486 507 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 496 517 pd boid; -#X obj 206 189 route 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 -19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 506 527 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 516 537 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 526 547 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 536 557 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 546 567 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 556 577 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 566 587 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 576 597 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 586 607 pd boid; -#N canvas 213 30 514 364 boid 0; -#X obj 100 24 gemhead; -#X obj 99 201 translateXYZ; -#X obj 192 162 unpack 0 0 0; -#X obj 192 1 inlet; -#X obj 100 155 alpha; -#X obj 101 85 color 1 0.5 0 0.5; -#N canvas 0 22 474 324 rand_color 0; -#X obj 47 130 random 1000; -#X obj 48 171 * 0.001; -#X obj 131 130 random 1000; -#X obj 132 171 * 0.001; -#X obj 214 131 random 1000; -#X obj 215 172 * 0.001; -#X obj 46 83 t b b b; -#X obj 48 256 outlet; -#X obj 47 26 r init; -#X obj 49 217 pack 0 0 0 0.5; -#X connect 0 0 1 0; -#X connect 1 0 9 0; -#X connect 2 0 3 0; -#X connect 3 0 9 1; -#X connect 4 0 5 0; -#X connect 5 0 9 2; -#X connect 6 0 0 0; -#X connect 6 1 2 0; -#X connect 6 2 4 0; -#X connect 8 0 6 0; -#X connect 9 0 7 0; -#X restore 214 58 pd rand_color; -#X obj 231 85 t 1; -#X obj 99 228 circle 0.05; -#X connect 0 0 5 0; -#X connect 1 0 8 0; -#X connect 2 0 1 1; -#X connect 2 1 1 2; -#X connect 2 2 1 3; -#X connect 3 0 2 0; -#X connect 4 0 1 0; -#X connect 5 0 4 0; -#X connect 6 0 5 1; -#X connect 6 0 7 0; -#X connect 7 0 4 1; -#X restore 596 617 pd boid; -#X connect 0 0 1 0; -#X connect 1 0 0 0; -#X connect 2 0 4 0; -#X connect 3 0 43 0; -#X connect 4 0 10 0; -#X connect 4 0 43 0; -#X connect 5 0 15 0; -#X connect 5 0 15 2; -#X connect 6 0 15 1; -#X connect 8 0 5 0; -#X connect 8 1 6 0; -#X connect 10 0 8 0; -#X connect 11 0 10 1; -#X connect 13 0 12 0; -#X connect 13 0 11 0; -#X connect 14 0 12 0; -#X connect 15 0 16 0; -#X connect 15 0 17 0; -#X connect 16 0 7 0; -#X connect 43 0 49 0; -#X connect 49 0 18 0; -#X connect 49 1 19 0; -#X connect 49 2 20 0; -#X connect 49 3 21 0; -#X connect 49 4 22 0; -#X connect 49 5 23 0; -#X connect 49 6 24 0; -#X connect 49 7 25 0; -#X connect 49 8 26 0; -#X connect 49 9 27 0; -#X connect 49 10 28 0; -#X connect 49 11 29 0; -#X connect 49 12 30 0; -#X connect 49 13 31 0; -#X connect 49 14 32 0; -#X connect 49 15 33 0; -#X connect 49 16 34 0; -#X connect 49 17 35 0; -#X connect 49 18 36 0; -#X connect 49 19 37 0; -#X connect 49 20 38 0; -#X connect 49 21 39 0; -#X connect 49 22 40 0; -#X connect 49 23 41 0; -#X connect 49 24 42 0; -#X connect 49 25 44 0; -#X connect 49 26 45 0; -#X connect 49 27 46 0; -#X connect 49 28 47 0; -#X connect 49 29 48 0; -#X connect 49 30 50 0; -#X connect 49 31 51 0; -#X connect 49 32 52 0; -#X connect 49 33 53 0; -#X connect 49 34 54 0; -#X connect 49 35 55 0; -#X connect 49 36 56 0; -#X connect 49 37 57 0; -#X connect 49 38 58 0; -#X connect 49 39 59 0; -#X restore 57 430 pd gem_example; -#X msg 266 592 flyrect \$1 \$2 \$3 \$4 \$5 \$6; -#X text 392 575 bounding box (walls) in which to fly (l/t/r/b/f/b) -; -#X text 389 614 point to which boids are attracted (x/y/z); -#X obj 266 574 pack 0 0 0 0 0 0; -#X floatatom 423 556 5 0 0 0 - - -; -#X floatatom 462 556 5 0 0 0 - - -; -#X obj -150 488 print boids3d; -#X msg 266 652 attractpt \$1 \$2 \$3; -#X obj 266 632 pack 0 0 0; -#X floatatom 345 615 5 0 0 0 - - -; -#X text -190 105 float/2d/3d adaptation 08/2005 by a. sier / jasch -; -#N canvas 754 114 178 480 init 0; -#X obj 34 21 loadbang; -#X obj 94 21 r reset; -#X msg 15 78 \; neighbors 4; -#X msg 15 168 \; center 1; -#X msg 15 228 \; match 1; -#X msg 15 318 \; edgedist 1; -#X msg 15 348 \; speed 3; -#X obj 16 49 b; -#X obj 17 21 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 --1; -#X msg 15 258 \; avoid 2; -#X msg 15 288 \; repel 2; -#X msg 15 378 \; inertia 8; -#X msg 15 138 \; minspeed 1; -#X msg 15 108 \; maxspeed 3; -#X msg 15 198 \; attract 3; -#X msg 15 408 \; accel 2; -#X msg 15 438 \; prefdist 1.5; -#X connect 0 0 7 0; -#X connect 1 0 7 0; -#X connect 7 0 2 0; -#X connect 7 0 13 0; -#X connect 7 0 12 0; -#X connect 7 0 3 0; -#X connect 7 0 14 0; -#X connect 7 0 4 0; -#X connect 7 0 9 0; -#X connect 7 0 10 0; -#X connect 7 0 6 0; -#X connect 7 0 11 0; -#X connect 7 0 15 0; -#X connect 7 0 16 0; -#X connect 8 0 7 0; -#X restore 57 411 pd init; -#N canvas 67 162 494 344 META 0; -#X text 12 165 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan -Wilkes for Pd version 0.42.; -#X text 12 145 AUTHOR Eric L. Singer; -#X text 12 5 KEYWORDS control; -#X text 12 45 DESCRIPTION bird flight and animal flock simulator; -#X text 12 65 INLET_0 bang mode dump reset number neighbors maxspeed -minspeed center attract match avoid repel edgedist speed inertia accel -prefdist flyrect attractpt; -#X text 12 105 OUTLET_0 list; -#X text 12 125 OUTLET_1 list; -#X text 12 25 LICENSE GPL v2; -#X restore 710 674 pd META; -#X obj -151 438 boids3d 16 0; -#X obj 604 10 import jasch_lib; -#X text -191 208 Boids takes an integer argument which is the number -of boids. Each time Boids receives a bang \, it calculates and outputs -the new positions of the boids. The output consists of the coordinates -for each boid \, the number and type depending on the mode.; -#X connect 0 0 48 0; -#X connect 1 0 47 0; -#X connect 2 0 1 0; -#X connect 3 0 4 0; -#X connect 4 0 47 0; -#X connect 5 0 6 0; -#X connect 6 0 47 0; -#X connect 7 0 8 0; -#X connect 8 0 47 0; -#X connect 9 0 10 0; -#X connect 10 0 47 0; -#X connect 11 0 12 0; -#X connect 12 0 47 0; -#X connect 13 0 14 0; -#X connect 14 0 47 0; -#X connect 15 0 81 0; -#X connect 16 0 17 0; -#X connect 17 0 47 0; -#X connect 18 0 19 0; -#X connect 19 0 47 0; -#X connect 20 0 21 0; -#X connect 21 0 47 0; -#X connect 22 0 23 0; -#X connect 23 0 47 0; -#X connect 24 0 25 0; -#X connect 25 0 47 0; -#X connect 26 0 27 0; -#X connect 27 0 47 0; -#X connect 28 0 48 0; -#X connect 35 0 71 0; -#X connect 36 0 71 1; -#X connect 37 0 71 2; -#X connect 38 0 71 3; -#X connect 39 0 76 0; -#X connect 40 0 76 1; -#X connect 41 0 42 0; -#X connect 42 0 47 0; -#X connect 44 0 45 0; -#X connect 45 0 48 0; -#X connect 66 0 81 0; -#X connect 68 0 47 0; -#X connect 71 0 68 0; -#X connect 72 0 71 4; -#X connect 73 0 71 5; -#X connect 75 0 47 0; -#X connect 76 0 75 0; -#X connect 77 0 76 2; -#X connect 81 0 74 0; -#X connect 81 1 64 0; diff --git a/boids3d/boids3d.c b/boids3d/boids3d.c deleted file mode 100644 index f8dd975..0000000 --- a/boids3d/boids3d.c +++ /dev/null @@ -1,956 +0,0 @@ -/* - - boids3d 2005 - 2006 a.sier / jasch - adapted from boids by eric singer © 1995-2003 eric l. singer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "m_pd.h" -#include -#include - -// constants -#define kAssistInlet 1 -#define kAssistOutlet 2 -#define kMaxLong 0xFFFFFFFF -#define kMaxNeighbors 4 - -// util -#define MAX(a,b) ((a)>(b)?(a):(b)) -#define CLIP(x,a,b) (x)=(x)<(a)?(a):(x)>(b)?(b):(x) - -// initial flight parameters -const short kNumBoids = 12; // number of boids -const short kNumNeighbors = 2; // must be <= kMaxNeighbors -const double kMinSpeed = 0.15; // boids' minimum speed -const double kMaxSpeed = 0.25; // boids' maximum speed -const double kCenterWeight = 0.25; // flock centering -const double kAttractWeight = 0.300;// attraction point seeking -const double kMatchWeight = 0.100;// neighbors velocity matching -const double kAvoidWeight = 0.10; // neighbors avoidance -const double kWallsWeight = 0.500;// wall avoidance [210] -const double kEdgeDist = 0.5; // vision distance to avoid wall edges [5] -const double kSpeedupFactor = 0.100;// alter animation speed -const double kInertiaFactor = 0.20; // willingness to change speed & direction -const double kAccelFactor = 0.100;// neighbor avoidance accelerate or decelerate rate -const double kPrefDist = 0.25; // preferred distance from neighbors -const double kFlyRectTop = 1.0; // fly rect boundaries -const double kFlyRectLeft = -1.0; -const double kFlyRectBottom = -1.0; -const double kFlyRectRight = 1.0; -const double kFlyRectFront = 1.0; -const double kFlyRectBack = -1.0; - - -// typedefs -typedef struct Velocity { - double x; - double y; - double z; -} Velocity; - -typedef struct Point3d { - double x; - double y; - double z; -} Point3d; - -typedef struct Box3D { - double left, right; - double top, bottom; - double front, back; -} Box3D; - -typedef struct _Boid { - Point3d oldPos; - Point3d newPos; - Velocity oldDir; - Velocity newDir; - double speed; - short neighbor[kMaxNeighbors]; - double neighborDistSqr[kMaxNeighbors]; -} t_one_boid, *BoidPtr; - -typedef struct _FlockObject { - t_object ob; - void *out1, *out2; - short mode; - long numBoids; - long numNeighbors; - Box3D flyRect; - double minSpeed; - double maxSpeed; - double centerWeight; - double attractWeight; - double matchWeight; - double avoidWeight; - double wallsWeight; - double edgeDist; - double speedupFactor; - double inertiaFactor; - double accelFactor; - double prefDist; - double prefDistSqr; - Point3d centerPt; - Point3d attractPt; - BoidPtr boid; - double d2r, r2d; -} t_boids, *FlockPtr; - - -t_symbol *ps_nothing; - -void *boids3d_class; -void *Flock_new(t_symbol *s, long argc, t_atom *argv); -void Flock_free(t_boids *x); -void Flock_bang(t_boids *x); -void Flock_dump(t_boids *x); -void Flock_mode(t_boids *x, t_float arg); -void Flock_numNeighbors(t_boids *x, t_float arg); -void Flock_numBoids(t_boids *x, t_float arg); -void Flock_minSpeed(t_boids *x, t_float arg); -void Flock_maxSpeed(t_boids *x, t_float arg); -void Flock_centerWeight(t_boids *x, t_float arg); -void Flock_attractWeight(t_boids *x, t_float arg); -void Flock_matchWeight(t_boids *x, t_float arg); -void Flock_avoidWeight(t_boids *x, t_float arg); -void Flock_wallsWeight(t_boids *x, t_float arg); -void Flock_edgeDist(t_boids *x, t_float arg); -void Flock_speedupFactor(t_boids *x, t_float arg); -void Flock_inertiaFactor(t_boids *x, t_float arg); -void Flock_accelFactor(t_boids *x, t_float arg); -void Flock_prefDist(t_boids *x, t_float arg); -void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv); -void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv); -void Flock_reset(t_boids *x); -void Flock_resetBoids(t_boids *x); -void InitFlock(t_boids *x); -void FlightStep(t_boids *x); -Point3d FindFlockCenter(t_boids *x); -float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel); -Velocity SeekPoint(t_boids *x, short theBoid, Point3d seekPt); -Velocity AvoidWalls(t_boids *x, short theBoid); -int InFront(BoidPtr theBoid, BoidPtr neighbor); -void NormalizeVelocity(Velocity *direction); -double RandomInt(double minRange, double maxRange); -double DistSqrToPt(Point3d firstPoint, Point3d secondPoint); - -void boids3d_setup(void) -{ - boids3d_class = class_new(gensym("boids3d"), (t_newmethod)Flock_new, - (t_method)Flock_free, sizeof(t_boids), 0, A_GIMME, 0); - class_addfloat(boids3d_class, (t_method) Flock_numBoids); - class_addbang(boids3d_class, (t_method) Flock_bang); - class_addmethod(boids3d_class, (t_method) Flock_numNeighbors, gensym("neighbors"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_numBoids, gensym("number"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_mode, gensym("mode"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_minSpeed, gensym("minspeed"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_maxSpeed, gensym("maxspeed"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_centerWeight, gensym("center"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_attractWeight, gensym("attract"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_matchWeight, gensym("match"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_avoidWeight, gensym("avoid"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_wallsWeight, gensym("repel"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_edgeDist, gensym("edgedist"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_speedupFactor, gensym("speed"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_inertiaFactor, gensym("inertia"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_accelFactor, gensym("accel"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_prefDist, gensym("prefdist"), A_FLOAT, 0); - class_addmethod(boids3d_class, (t_method) Flock_flyRect, gensym("flyrect"), A_GIMME, 0); - class_addmethod(boids3d_class, (t_method) Flock_attractPt, gensym("attractpt"), A_GIMME, 0); - class_addmethod(boids3d_class, (t_method) Flock_resetBoids, gensym("reset"), 0); - class_addmethod(boids3d_class, (t_method) Flock_reset, gensym("init"), 0); - class_addmethod(boids3d_class, (t_method) Flock_dump, gensym("dump"), 0); - - post("boids3d 2005-2006 a.sier / jasch © 1995-2003 eric l. singer "__DATE__" "__TIME__); - ps_nothing = gensym(""); -} - - -void *Flock_new(t_symbol *s, long argc, t_atom *argv) -{ - t_boids *x = (t_boids *)pd_new(boids3d_class); - x->out1 = outlet_new(&x->ob, NULL); - x->out2 = outlet_new(&x->ob, NULL); - - x->numBoids = 16; - if((argc >= 1) && (argv[0].a_type == A_FLOAT)){ - x->numBoids = argv[0].a_w.w_float; - } - x->boid = (t_one_boid *)malloc(sizeof(t_one_boid) * x->numBoids); - - InitFlock(x); - - x->mode = 0; - if((argc >= 2) && (argv[1].a_type == A_FLOAT)){ - x->mode = (short)(CLIP(argv[1].a_w.w_float, 0, 2)); - } - - x->d2r = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068/180.0; - x->r2d = 180.0/3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068; - - return(x); -} - -void Flock_free(t_boids *x) -{ - free(x->boid); -} - -void Flock_bang(t_boids *x) -{ - short i; - t_atom outlist[10]; - t_atom *out; - - double tempNew_x, tempNew_y, tempNew_z; - double tempOld_x, tempOld_y, tempOld_z; - double delta_x, delta_y, delta_z; - double azi, ele, speed; - - out = outlist; - - FlightStep(x); - - - switch(x->mode) { // newpos - case 0: - for (i = 0; i < x->numBoids; i++){ - SETFLOAT(out+0, i); - SETFLOAT(out+1, x->boid[i].newPos.x); - SETFLOAT(out+2, x->boid[i].newPos.y); - SETFLOAT(out+3, x->boid[i].newPos.z); - outlet_list(x->out1, 0L, 4, out); - } - break; - case 1: //newpos + oldpos - for (i = 0; i < x->numBoids; i++){ - SETFLOAT(out+0, i); - SETFLOAT(out+1, x->boid[i].newPos.x); - SETFLOAT(out+2, x->boid[i].newPos.y); - SETFLOAT(out+3, x->boid[i].newPos.z); - SETFLOAT(out+4, x->boid[i].oldPos.x); - SETFLOAT(out+5, x->boid[i].oldPos.y); - SETFLOAT(out+6, x->boid[i].oldPos.z); - outlet_list(x->out1, 0L, 7, out); - } - break; - case 2: - for (i = 0; i < x->numBoids; i++){ - tempNew_x = x->boid[i].newPos.x; - tempNew_y = x->boid[i].newPos.y; - tempNew_z = x->boid[i].newPos.z; - tempOld_x = x->boid[i].oldPos.x; - tempOld_y = x->boid[i].oldPos.y; - tempOld_z = x->boid[i].oldPos.z; - delta_x = tempNew_x - tempOld_x; - delta_y = tempNew_y - tempOld_y; - delta_z = tempNew_z - tempOld_z; - azi = atan2(delta_y, delta_x) * x->r2d; - ele = atan2(delta_y, delta_x) * x->r2d; - speed = sqrt(delta_x * delta_x + delta_y * delta_y + delta_z * delta_z); - SETFLOAT(out+0, i); - SETFLOAT(out+1, tempNew_x); - SETFLOAT(out+2, tempNew_y); - SETFLOAT(out+3, tempNew_z); - SETFLOAT(out+4, tempOld_x); - SETFLOAT(out+5, tempOld_y); - SETFLOAT(out+6, tempOld_z); - SETFLOAT(out+7, speed); - SETFLOAT(out+8, azi); - SETFLOAT(out+9, ele); - outlet_list(x->out1, 0L, 10, out); - } - break; - } -} - -void Flock_dump(t_boids *x) -{ - t_atom outList[6]; - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->numNeighbors; - outlet_anything(x->out2, gensym("neighbors"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->minSpeed; - outlet_anything(x->out2, gensym("minspeed"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->maxSpeed; - outlet_anything(x->out2, gensym("maxspeed"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->centerWeight; - outlet_anything(x->out2, gensym("center"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->attractWeight; - outlet_anything(x->out2, gensym("attract"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->matchWeight; - outlet_anything(x->out2, gensym("match"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->avoidWeight; - outlet_anything(x->out2, gensym("avoid"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->wallsWeight; - outlet_anything(x->out2, gensym("repel"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->edgeDist; - outlet_anything(x->out2, gensym("edgedist"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->speedupFactor; - outlet_anything(x->out2, gensym("speed"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->inertiaFactor; - outlet_anything(x->out2, gensym("inertia"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->accelFactor; - outlet_anything(x->out2, gensym("accel"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->prefDist; - outlet_anything(x->out2, gensym("prefdist"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->flyRect.left; - outList[1].a_type = A_FLOAT; - outList[1].a_w.w_float = x->flyRect.top; - outList[2].a_type = A_FLOAT; - outList[2].a_w.w_float = x->flyRect.right; - outList[3].a_type = A_FLOAT; - outList[3].a_w.w_float = x->flyRect.bottom; - outList[4].a_type = A_FLOAT; - outList[4].a_w.w_float = x->flyRect.front; - outList[5].a_type = A_FLOAT; - outList[5].a_w.w_float = x->flyRect.back; - outlet_anything(x->out2, gensym("flyrect"), 6, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->attractPt.x; - outList[1].a_type = A_FLOAT; - outList[1].a_w.w_float = x->attractPt.y; - outList[2].a_type = A_FLOAT; - outList[2].a_w.w_float = x->attractPt.z; - outlet_anything(x->out2, gensym("attractpt"), 3, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->mode; - outlet_anything(x->out2, gensym("mode"), 1, outList); - - outList[0].a_type = A_FLOAT; - outList[0].a_w.w_float = x->numBoids; - outlet_anything(x->out2, gensym("number"), 1, outList); -} - - -void Flock_mode(t_boids *x, t_float arg) -{ - long m = (long)arg; - x->mode = CLIP(m, 0, 2); -} - -void Flock_numNeighbors(t_boids *x, t_float arg) -{ - x->numNeighbors = (long)arg; -} - -void Flock_numBoids(t_boids *x, t_float arg) -{ - x->boid = (t_one_boid *)realloc(x->boid, sizeof(t_one_boid) * (long)arg); - x->numBoids = (long)arg; - Flock_resetBoids(x); -} - -void Flock_minSpeed(t_boids *x, t_float arg) -{ - x->minSpeed = MAX(arg, 0.000001); -} - -void Flock_maxSpeed(t_boids *x, t_float arg) -{ - x->maxSpeed = (double)arg; -} - -void Flock_centerWeight(t_boids *x, t_float arg) -{ - x->centerWeight = (double)arg; -} - -void Flock_attractWeight(t_boids *x, t_float arg) -{ - x->attractWeight = (double)arg; -} - -void Flock_matchWeight(t_boids *x, t_float arg) -{ - x->matchWeight = (double)arg; -} - -void Flock_avoidWeight(t_boids *x, t_float arg) -{ - x->avoidWeight = (double)arg; -} - -void Flock_wallsWeight(t_boids *x, t_float arg) -{ - x->wallsWeight = (double)arg; -} - -void Flock_edgeDist(t_boids *x, t_float arg) -{ - x->edgeDist = (double)arg; -} - -void Flock_speedupFactor(t_boids *x, t_float arg) -{ - x->speedupFactor = (double)arg; -} - -void Flock_inertiaFactor(t_boids *x, t_float arg) -{ - if(arg == 0){ - x->inertiaFactor = 0.000001; - }else{ - x->inertiaFactor = (double)arg; - } -} - -void Flock_accelFactor(t_boids *x, t_float arg) -{ - x->accelFactor = (double)arg; -} - -void Flock_prefDist(t_boids *x, t_float arg) -{ - x->prefDist = (double)arg; -} - -void Flock_flyRect(t_boids *x, t_symbol *msg, short argc, t_atom *argv) -{ - double temp[6]; - short i; - if(argc == 6){ - for(i = 0; i < 6; i++) { - if(argv[i].a_type == A_FLOAT) { - temp[i] = (double)argv[i].a_w.w_float; - } - } - x->flyRect.left = temp[0]; - x->flyRect.top = temp[1]; - x->flyRect.right = temp[2]; - x->flyRect.bottom = temp[3]; - x->flyRect.front = temp[4]; - x->flyRect.back = temp[5]; - }else{ - error("boids3d: flyrect needs 6 values"); - } -} - -void Flock_attractPt(t_boids *x, t_symbol *msg, short argc, t_atom *argv) -{ - double temp[3]; - short i; - if(argc == 3){ - for(i = 0; i < 3 ; i++) { - if(argv[i].a_type == A_FLOAT) { - temp[i] = (double)argv[i].a_w.w_float; - } - } - x->attractPt.x = temp[0]; - x->attractPt.y = temp[1]; - x->attractPt.z = temp[2]; - }else{ - error("boids3d: attractPt needs 3 values"); - } -} - -void Flock_reset(t_boids *x) -{ - InitFlock(x); -} - -void Flock_resetBoids(t_boids *x) -{ - long i, j; - double rndAngle; - - for (i = 0; i < x->numBoids; i++) { // init everything to 0.0 - x->boid[i].oldPos.x = 0.0; - x->boid[i].oldPos.y = 0.0; - x->boid[i].oldPos.z = 0.0; - - x->boid[i].newPos.x = 0.0; - x->boid[i].newPos.y = 0.0; - x->boid[i].newPos.z = 0.0; - - x->boid[i].oldDir.x = 0.0; - x->boid[i].oldDir.y = 0.0; - x->boid[i].oldDir.z = 0.0; - - x->boid[i].newDir.x = 0.0; - x->boid[i].newDir.y = 0.0; - x->boid[i].newDir.z = 0.0; - - x->boid[i].speed = 0.0; - - for(j=0; jboid[i].neighbor[j] = 0; - x->boid[i].neighborDistSqr[j] = 0.0; - } - } - for (i = 0; i < x->numBoids; i++) { // set the initial locations and velocities of the boids - x->boid[i].newPos.x = x->boid[i].oldPos.x = RandomInt(x->flyRect.right,x->flyRect.left); // set random location within flyRect - x->boid[i].newPos.y = x->boid[i].oldPos.y = RandomInt(x->flyRect.bottom, x->flyRect.top); - x->boid[i].newPos.z = x->boid[i].oldPos.z = RandomInt(x->flyRect.back, x->flyRect.front); - rndAngle = RandomInt(0, 360) * x->d2r; // set velocity from random angle - x->boid[i].newDir.x = sin(rndAngle); - x->boid[i].newDir.y = cos(rndAngle); - x->boid[i].newDir.z = (cos(rndAngle) + sin(rndAngle)) * 0.5; - x->boid[i].speed = (kMaxSpeed + kMinSpeed) * 0.5; - } -} - -void InitFlock(t_boids *x) -{ - x->numNeighbors = kNumNeighbors; - x->minSpeed = kMinSpeed; - x->maxSpeed = kMaxSpeed; - x->centerWeight = kCenterWeight; - x->attractWeight = kAttractWeight; - x->matchWeight = kMatchWeight; - x->avoidWeight = kAvoidWeight; - x->wallsWeight = kWallsWeight; - x->edgeDist = kEdgeDist; - x->speedupFactor = kSpeedupFactor; - x->inertiaFactor = kInertiaFactor; - x->accelFactor = kAccelFactor; - x->prefDist = kPrefDist; - x->prefDistSqr = kPrefDist * kPrefDist; - x->flyRect.top = kFlyRectTop; - x->flyRect.left = kFlyRectLeft; - x->flyRect.bottom = kFlyRectBottom; - x->flyRect.right = kFlyRectRight; - x->flyRect.front = kFlyRectFront; - x->flyRect.back = kFlyRectBack; - x->attractPt.x = (kFlyRectLeft + kFlyRectRight) * 0.5; - x->attractPt.y = (kFlyRectTop + kFlyRectBottom) * 0.5; - x->attractPt.z = (kFlyRectFront + kFlyRectBack) * 0.5; - Flock_resetBoids(x); -} - -void FlightStep(t_boids *x) -{ - Velocity goCenterVel; - Velocity goAttractVel; - Velocity matchNeighborVel; - Velocity avoidWallsVel; - Velocity avoidNeighborVel; - float avoidNeighborSpeed; - const Velocity zeroVel = {0.0, 0.0, 0.0}; - short i; - - x->centerPt = FindFlockCenter(x); - for (i = 0; i < x->numBoids; i++) { // save position and velocity - x->boid[i].oldPos.x = x->boid[i].newPos.x; - x->boid[i].oldPos.y = x->boid[i].newPos.y; - x->boid[i].oldPos.z = x->boid[i].newPos.z; - - x->boid[i].oldDir.x = x->boid[i].newDir.x; - x->boid[i].oldDir.y = x->boid[i].newDir.y; - x->boid[i].oldDir.z = x->boid[i].newDir.z; - } - for (i = 0; i < x->numBoids; i++) { - if (x->numNeighbors > 0) { // get all velocity components - avoidNeighborSpeed = MatchAndAvoidNeighbors(x, i,&matchNeighborVel, &avoidNeighborVel); - } else { - matchNeighborVel = zeroVel; - avoidNeighborVel = zeroVel; - avoidNeighborSpeed = 0; - } - goCenterVel = SeekPoint(x, i, x->centerPt); - goAttractVel = SeekPoint(x, i, x->attractPt); - avoidWallsVel = AvoidWalls(x, i); - - // compute resultant velocity using weights and inertia - x->boid[i].newDir.x = x->inertiaFactor * (x->boid[i].oldDir.x) + - (x->centerWeight * goCenterVel.x + - x->attractWeight * goAttractVel.x + - x->matchWeight * matchNeighborVel.x + - x->avoidWeight * avoidNeighborVel.x + - x->wallsWeight * avoidWallsVel.x) / x->inertiaFactor; - x->boid[i].newDir.y = x->inertiaFactor * (x->boid[i].oldDir.y) + - (x->centerWeight * goCenterVel.y + - x->attractWeight * goAttractVel.y + - x->matchWeight * matchNeighborVel.y + - x->avoidWeight * avoidNeighborVel.y + - x->wallsWeight * avoidWallsVel.y) / x->inertiaFactor; - x->boid[i].newDir.z = x->inertiaFactor * (x->boid[i].oldDir.z) + - (x->centerWeight * goCenterVel.z + - x->attractWeight * goAttractVel.z + - x->matchWeight * matchNeighborVel.z + - x->avoidWeight * avoidNeighborVel.z + - x->wallsWeight * avoidWallsVel.z) / x->inertiaFactor; - NormalizeVelocity(&(x->boid[i].newDir)); // normalize velocity so its length is unity - - // set to avoidNeighborSpeed bounded by minSpeed and maxSpeed - if ((avoidNeighborSpeed >= x->minSpeed) && - (avoidNeighborSpeed <= x->maxSpeed)) - x->boid[i].speed = avoidNeighborSpeed; - else if (avoidNeighborSpeed > x->maxSpeed) - x->boid[i].speed = x->maxSpeed; - else - x->boid[i].speed = x->minSpeed; - - // calculate new position, applying speedupFactor - x->boid[i].newPos.x += x->boid[i].newDir.x * x->boid[i].speed * (x->speedupFactor / 100.0); - x->boid[i].newPos.y += x->boid[i].newDir.y * x->boid[i].speed * (x->speedupFactor / 100.0); - x->boid[i].newPos.z += x->boid[i].newDir.z * x->boid[i].speed * (x->speedupFactor / 100.0); - - } -} - -Point3d FindFlockCenter(t_boids *x) -{ - double totalH = 0, totalV = 0, totalD = 0; - Point3d centerPoint; - register short i; - - for (i = 0 ; i < x->numBoids; i++) - { - totalH += x->boid[i].oldPos.x; - totalV += x->boid[i].oldPos.y; - totalD += x->boid[i].oldPos.z; - } - centerPoint.x = (double) (totalH / x->numBoids); - centerPoint.y = (double) (totalV / x->numBoids); - centerPoint.z = (double) (totalD / x->numBoids); - - return(centerPoint); -} - -float MatchAndAvoidNeighbors(t_boids *x, short theBoid, Velocity *matchNeighborVel, Velocity *avoidNeighborVel) -{ - short i, j, neighbor; - double distSqr; - double dist, distH, distV,distD; - double tempSpeed; - short numClose = 0; - Velocity totalVel = {0.0, 0.0, 0.0}; - - /**********************/ - /* Find the neighbors */ - /**********************/ - - /* special case of one neighbor */ - if (x->numNeighbors == 1) { - x->boid[theBoid].neighborDistSqr[0] = kMaxLong; - - for (i = 0; i < x->numBoids; i++) { - if (i != theBoid) { - distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); - - /* if this one is closer than the closest so far, then remember it */ - if (x->boid[theBoid].neighborDistSqr[0] > distSqr) { - x->boid[theBoid].neighborDistSqr[0] = distSqr; - x->boid[theBoid].neighbor[0] = i; - } - } - } - } - /* more than one neighbor */ - else { - for (j = 0; j < x->numNeighbors; j++) - x->boid[theBoid].neighborDistSqr[j] = kMaxLong; - - for (i = 0 ; i < x->numBoids; i++) { - /* if this one is not me... */ - if (i != theBoid) { - distSqr = DistSqrToPt(x->boid[theBoid].oldPos, x->boid[i].oldPos); - - /* if distSqr is less than the distance at the bottom of the array, sort into array */ - if (distSqr < x->boid[theBoid].neighborDistSqr[x->numNeighbors-1]) { - j = x->numNeighbors - 1; - - /* sort distSqr in to keep array in size order, smallest first */ - while ((distSqr < x->boid[theBoid].neighborDistSqr[j-1]) && (j > 0)) { - x->boid[theBoid].neighborDistSqr[j] = x->boid[theBoid].neighborDistSqr[j - 1]; - x->boid[theBoid].neighbor[j] = x->boid[theBoid].neighbor[j - 1]; - j--; - } - x->boid[theBoid].neighborDistSqr[j] = distSqr; - x->boid[theBoid].neighbor[j] = i; - } - } - } - } - - /*********************************/ - /* Match and avoid the neighbors */ - /*********************************/ - - matchNeighborVel->x = 0; - matchNeighborVel->y = 0; - matchNeighborVel->z = 0; - - // set tempSpeed to old speed - tempSpeed = x->boid[theBoid].speed; - - for (i = 0; i < x->numNeighbors; i++) { - neighbor = x->boid[theBoid].neighbor[i]; - - // calculate matchNeighborVel by averaging the neighbor velocities - matchNeighborVel->x += x->boid[neighbor].oldDir.x; - matchNeighborVel->y += x->boid[neighbor].oldDir.y; - matchNeighborVel->z += x->boid[neighbor].oldDir.z; - - // if distance is less than preferred distance, then neighbor influences boid - distSqr = x->boid[theBoid].neighborDistSqr[i]; - if (distSqr < x->prefDistSqr) { - dist = sqrt(distSqr); - - distH = x->boid[neighbor].oldPos.x - x->boid[theBoid].oldPos.x; - distV = x->boid[neighbor].oldPos.y - x->boid[theBoid].oldPos.y; - distD = x->boid[neighbor].oldPos.z - x->boid[theBoid].oldPos.z; - - if(dist == 0.0) dist = 0.0000001; - totalVel.x = totalVel.x - distH - (distH * ((float) x->prefDist / (dist))); - totalVel.y = totalVel.y - distV - (distV * ((float) x->prefDist / (dist))); - totalVel.z = totalVel.z - distD - (distV * ((float) x->prefDist / (dist))); - - numClose++; - } - if (InFront(&(x->boid[theBoid]), &(x->boid[neighbor]))) { // adjust speed - if (distSqr < x->prefDistSqr) - tempSpeed /= (x->accelFactor / 100.0); - else - tempSpeed *= (x->accelFactor / 100.0); - } - else { - if (distSqr < x->prefDistSqr) - tempSpeed *= (x->accelFactor / 100.0); - else - tempSpeed /= (x->accelFactor / 100.0); - } - } - if (numClose) { - avoidNeighborVel->x = totalVel.x / numClose; - avoidNeighborVel->y = totalVel.y / numClose; - avoidNeighborVel->z = totalVel.z / numClose; - NormalizeVelocity(matchNeighborVel); - } - else { - avoidNeighborVel->x = 0; - avoidNeighborVel->y = 0; - avoidNeighborVel->z = 0; - } - return(tempSpeed); -} - - -Velocity SeekPoint(t_boids *x, short theBoid, Point3d seekPt) -{ - Velocity tempDir; - tempDir.x = seekPt.x - x->boid[theBoid].oldPos.x; - tempDir.y = seekPt.y - x->boid[theBoid].oldPos.y; - tempDir.z = seekPt.z - x->boid[theBoid].oldPos.z; - NormalizeVelocity(&tempDir); - return(tempDir); -} - - -Velocity AvoidWalls(t_boids *x, short theBoid) -{ - Point3d testPoint; - Velocity tempVel = {0.0, 0.0, 0.0}; - - /* calculate test point in front of the nose of the boid */ - /* distance depends on the boid's speed and the avoid edge constant */ - testPoint.x = x->boid[theBoid].oldPos.x + x->boid[theBoid].oldDir.x * x->boid[theBoid].speed * x->edgeDist; - testPoint.y = x->boid[theBoid].oldPos.y + x->boid[theBoid].oldDir.y * x->boid[theBoid].speed * x->edgeDist; - testPoint.z = x->boid[theBoid].oldPos.z + x->boid[theBoid].oldDir.z * x->boid[theBoid].speed * x->edgeDist; - - /* if test point is out of the left (right) side of x->flyRect, */ - /* return a positive (negative) horizontal velocity component */ - if (testPoint.x < x->flyRect.left) - tempVel.x = fabs(x->boid[theBoid].oldDir.x); - else if (testPoint.x > x->flyRect.right) - tempVel.x = - fabs(x->boid[theBoid].oldDir.x); - - /* same with top and bottom */ - if (testPoint.y < x->flyRect.top) - tempVel.y = fabs(x->boid[theBoid].oldDir.y); - else if (testPoint.y > x->flyRect.bottom) - tempVel.y = - fabs(x->boid[theBoid].oldDir.y); - - /* same with front and back */ - if (testPoint.z < x->flyRect.front) - tempVel.z = fabs(x->boid[theBoid].oldDir.z); - else if (testPoint.z > x->flyRect.back) - tempVel.z = - fabs(x->boid[theBoid].oldDir.z); - - return(tempVel); -} - - -int InFront(BoidPtr theBoid, BoidPtr neighbor) -{ - float grad, intercept; - int result; - -/* - -Find the gradient and y-intercept of a line passing through theBoid's oldPos -perpendicular to its direction of motion. Another boid is in front of theBoid -if it is to the right or left of this linedepending on whether theBoid is moving -right or left. However, if theBoid is travelling vertically then just compare -their vertical coordinates. - -*/ - // xy plane - - // if theBoid is not travelling vertically... - if (theBoid->oldDir.x != 0) { - // calculate gradient of a line _perpendicular_ to its direction (hence the minus) - grad = -theBoid->oldDir.y / theBoid->oldDir.x; - - // calculate where this line hits the y axis (from y = mx + c) - intercept = theBoid->oldPos.y - (grad * theBoid->oldPos.x); - - /* compare the horizontal position of the neighbor boid with */ - /* the point on the line that has its vertical coordinate */ - if (neighbor->oldPos.x >= ((neighbor->oldPos.y - intercept) / grad)) { - /* return true if the first boid's horizontal movement is +ve */ - result = (theBoid->oldDir.x > 0); - - if (result==0) return 0; - else goto next; - - } else { - /* return true if the first boid's horizontal movement is +ve */ - result = (theBoid->oldDir.x < 0); - if (result==0) return 0; - else goto next; - } - } - /* else theBoid is travelling vertically, so just compare vertical coordinates */ - else if (theBoid->oldDir.y > 0) { - result = (neighbor->oldPos.y > theBoid->oldPos.y); - if (result==0){ - return 0; - }else{ - goto next; - } - }else{ - result = (neighbor->oldPos.y < theBoid->oldPos.y); - if (result==0){ - return 0; - } else { - goto next; - } - } -next: - // yz plane - - // if theBoid is not travelling vertically... - if (theBoid->oldDir.y != 0) { - // calculate gradient of a line _perpendicular_ to its direction (hence the minus) - grad = -theBoid->oldDir.z / theBoid->oldDir.y; - - // calculate where this line hits the y axis (from y = mx + c) - intercept = theBoid->oldPos.z - (grad * theBoid->oldPos.y); - - // compare the horizontal position of the neighbor boid with - // the point on the line that has its vertical coordinate - if (neighbor->oldPos.y >= ((neighbor->oldPos.z - intercept) / grad)) { - // return true if the first boid's horizontal movement is +ve - result = (theBoid->oldDir.y > 0); - if (result==0){ - return 0; - }else{ - goto next2; - } - } else { - // return true if the first boid's horizontal movement is +ve - result = (theBoid->oldDir.y < 0); - if (result==0){ - return 0; - }else{ - goto next2; - } - } - } - // else theBoid is travelling vertically, so just compare vertical coordinates - else if (theBoid->oldDir.z > 0) { - result = (neighbor->oldPos.z > theBoid->oldPos.z); - if (result==0){ - return 0; - }else{ - goto next2; - } - }else{ - result = (neighbor->oldPos.z < theBoid->oldPos.z); - if (result==0){ - return 0; - }else{ - goto next2; - } - } -next2: - return 1; -} - -void NormalizeVelocity(Velocity *direction) -{ - float my_hypot; - - my_hypot = sqrt(direction->x * direction->x + direction->y * direction->y + direction->z * direction->z ); - - if (my_hypot != 0.0) { - direction->x = direction->x / my_hypot; - direction->y = direction->y / my_hypot; - direction->z = direction->z / my_hypot; - } -} - -double RandomInt(double minRange, double maxRange) -{ - unsigned short qdRdm; - double t, result; - - qdRdm = rand(); - t = (double)qdRdm / 65536.0; // now 0 <= t <= 1 - result = (t * (maxRange - minRange)) + minRange; - return(result); -} - -double DistSqrToPt(Point3d firstPoint, Point3d secondPoint) -{ - double a, b,c; - a = firstPoint.x - secondPoint.x; - b = firstPoint.y - secondPoint.y; - c = firstPoint.z - secondPoint.z; - return(a * a + b * b + c * c); -} \ No newline at end of file diff --git a/boids3d/makefile b/boids3d/makefile deleted file mode 100644 index b2f087e..0000000 --- a/boids3d/makefile +++ /dev/null @@ -1,92 +0,0 @@ -NAME=boids3d -CSYM=boids3d - -current: pd_darwin - -# ----------------------- NT ----------------------- - -pd_nt: $(NAME).dll - -.SUFFIXES: .dll - -PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo -VC="C:\Program Files\Microsoft Visual Studio\Vc98" - -PDNTINCLUDE = /I. /I..\..\src /I$(VC)\include - -PDNTLDIR = $(VC)\lib -PDNTLIB = $(PDNTLDIR)\libc.lib \ - $(PDNTLDIR)\oldnames.lib \ - $(PDNTLDIR)\kernel32.lib \ - ..\..\bin\pd.lib - -.c.dll: - cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c - link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) - -# ----------------------- IRIX 5.x ----------------------- - -pd_irix5: $(NAME).pd_irix5 - -.SUFFIXES: .pd_irix5 - -SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 - -SGIINCLUDE = -I../../src - -.c.pd_irix5: - $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c - ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o - rm $*.o - -# ----------------------- IRIX 6.x ----------------------- - -pd_irix6: $(NAME).pd_irix6 - -.SUFFIXES: .pd_irix6 - -SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ - -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ - -Ofast=ip32 - -.c.pd_irix6: - $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c - ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o - rm $*.o - -# ----------------------- LINUX i386 ----------------------- - -pd_linux: $(NAME).pd_linux - -.SUFFIXES: .pd_linux - -LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \ - -Wall -W -Wshadow -Wstrict-prototypes \ - -Wno-unused -Wno-parentheses -Wno-switch $(CFLAGS) - -LINUXINCLUDE = -I../../src - -.c.pd_linux: - $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - ld --export-dynamic -shared -o $*.pd_linux $*.o -lc -lm - strip --strip-unneeded $*.pd_linux - rm -f $*.o - -# ----------------------- Mac OSX ----------------------- - -pd_darwin: $(NAME).pd_darwin - -.SUFFIXES: .pd_darwin - -DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ - -Wno-unused -Wno-parentheses -Wno-switch - -.c.pd_darwin: - $(CC) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c - $(CC) -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o - rm -f $*.o - -# ---------------------------------------------------------- - -clean: - rm -f *.o *.pd_* so_locations diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..de60a83 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +pd-boids (1.1-1) unstable; urgency=low + + * Initial release (Closes: #nnnn) + + -- Hans-Christoph Steiner Thu, 21 Jan 2010 23:27:04 -0500 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +7 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..bf159b1 --- /dev/null +++ b/debian/control @@ -0,0 +1,31 @@ +Source: pd-boids +Section: sound +Priority: optional +Maintainer: Debian Multimedia Maintainers +Uploaders: Hans-Christoph Steiner +Build-Depends: debhelper (>= 7.0.50~), + puredata +Standards-Version: 3.9.1 +Homepage: http://puredata.info + +Package: pd-boids +Architecture: any +Depends: ${shlibs:Depends}, + pd, + pd-libdir, + ${misc:Depends} +Recommends: pd-import, + gem +Description: a Pd library for the "boids" flocking simulator algorithm + Boids is a bird flight and animal flock simulator. It is based on the + same algorithm which was used in Jurassic Park for the herding + dinosaurs. Boids takes an integer argument which is the number of + boids. Each time Boids receives a bang, it calculates and outputs the + new positions of the boids. The output consists of thew coordiantes + for each boid, the number and type depending on the mode. + . + The flight parameters can be changed with messages. Use the 'dump' + message to output a list of the current parameter settings. + . + For more information about the Boids algorithm, see Craig Reynolds' + Web site at "http://reality.sgi.com/employees/craig/boids.html". diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..c2e22c5 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,25 @@ +Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=135 +Name: boids +Maintainer: Jan Schacher +Source: http://sourceforge.net/projects/pure-data/files/libraries/boids/ + +Files: * +Copyright: 1995-1998, Eric Singer + 2005, Andre Sier + 2005,2007, Jan Schacher +License: GPL-2+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +X-Comment: On Debian systems, the complete text of the GNU General + Public License can be found in `/usr/share/common-licenses/GPL-2'. diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000..ae1dc36 --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,7 @@ +[DEFAULT] +upstream-branch = upstream +debian-branch = master +upstream-tag = upstream/%(version)s +debian-tag = debian/%(version)s +pristine-tar = True +sign-tags = True diff --git a/debian/links b/debian/links new file mode 100644 index 0000000..c010096 --- /dev/null +++ b/debian/links @@ -0,0 +1,3 @@ +usr/lib/pd/extra/boids/README.txt usr/share/doc/pd-boids/README +usr/lib/pd/extra/boids/examples usr/share/doc/pd-boids/examples +usr/share/common-licenses/GPL-2 usr/lib/pd/extra/boids/LICENSE.txt diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..1a63779 --- /dev/null +++ b/debian/rules @@ -0,0 +1,17 @@ +#!/usr/bin/make -f + +LIBRARY_NAME = boids +PACKAGE = pd-$(LIBRARY_NAME) +pkglibdir = /usr/lib/pd/extra + +%: + dh $@ --buildsystem=makefile + +override_dh_auto_install: + dh_auto_install -- prefix=/usr pkglibdir=$(pkglibdir) +# replace license file with link to the Debian license file + rm -f -- $(CURDIR)/debian/$(PACKAGE)/$(pkglibdir)/$(LIBRARY_NAME)/LICENSE.txt + +override_dh_shlibdeps: + dpkg-shlibdeps $(CURDIR)/debian/$(PACKAGE)$(pkglibdir)/$(LIBRARY_NAME)/*.pd_linux \ + -T$(CURDIR)/debian/$(PACKAGE).substvars diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..82c0d1a --- /dev/null +++ b/debian/watch @@ -0,0 +1,2 @@ +version=3 +http://sf.net/pure-data/template-(.*)\.tar\.gz -- cgit v1.2.1