from c4d import * import math import random #Boids for Py4D by smart-page.net #environment minx = -2000 maxx = 2000 miny = 1000 maxy = 3000 minz = -2000 maxz = 2000 #boids params target_maxspeed = 60 boid_maxspeed = 50 boid_distance = 200 theboids = [] target = Vector() rand = None targetvec = Vector(0) tps = [] bpos = None bvel = None def set_random(): global rand rand = random.Random(1) rand.seed(20) set_random() def create_particles(): for x in xrange(0, 100): p = TParticle(doc) tps.append(p) p.set_life(BaseTime(100)) def main(): global tp global doc global theboids global bpos global bvel frame = doc.get_time().get_frame(doc.get_fps()) if frame==0: tp.free_all_particles() #if frame<13: set_random() create_particles() theboids = [] bpos = [] bvel = [] for i, myboid in enumerate(tp.get_particles()): theboids.append(myboid) bpos.append(myboid.get_pos()) bvel.append(myboid.get_vel()) moveboids(myboid, i) movetarget() set_target() def set_target(): v = Vector() for x in bpos: v +=x v = v / tp.count_all_particles() op[ID_USERDATA, 1].set_pos(v) def moveboids(boid, c): v1 = rule1(theboids, c) v2 = rule2(theboids, c) v3 = rule3(theboids, c) v4 = rule4(c) bvel[c] += v1 + v2 + v3 + v4 bvel[c] = limitspeed(bvel[c], boid_maxspeed) boid.set_vel(bvel[c]) boid.set_pos(bpos[c] + bvel[c]) def rule1(boids, c): v = Vector() for i, b in enumerate(boids): boid_pos = bpos[c] b_pos = bpos[i] if b_pos == boid_pos: continue v += boid_pos - b_pos v /= tp.count_all_particles() return bvel[c] -v / 100 def rule2(boids, c): d = 0 k = 0 for i, b in enumerate(boids): if (bpos[i] - bpos[c]).len() < boid_distance: k += 1 pos = bpos[c] dif = (pos - bpos[i]) if dif >= 0: dif = math.sqrt(boid_distance) - dif elif dif < 0: dif = -math.sqrt(boid_distance) - dif d += dif if k == 0: return return bvel[c] - d / 4 def rule3(boids, c): v=Vector() for b in boids: v += bvel[c] v /= tp.count_all_particles() return bvel[c]+v/30 def rule4(c): return (target - bpos[c]) / 100 def movetarget(): global target global targetvec if target.x < minx or target.y < miny or target.z < minz: targetvec.x+=rand.random() * target_maxspeed targetvec.y+=rand.random() * target_maxspeed targetvec.z+=rand.random() * target_maxspeed if target.x > maxx or target.y > maxy or target.z > maxz: targetvec.x-=rand.random() * target_maxspeed targetvec.y-=rand.random() * target_maxspeed targetvec.z-=rand.random() * target_maxspeed targetvec = limitspeed(targetvec, target_maxspeed) target += targetvec def limitspeed(v, speed): if v.len() > speed: v = v*(speed / v.len()) return v