def test_StaticEmitter_discrete(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter masses = (0.5, 2.0, 8.0) positions = ((1.0, 1.0, 1.0), (10.0, 20.0, 30.0), (-100.0, 0.0, 0.0)) velocities = ((1, 1, 0), ) colors = ((1.0, 1.0, 1.0, 0.5), (1.0, 0, 0, 1.0), (0, 1.0, 0, 1.0)) emitter = StaticEmitter(rate=1, mass=masses, position=positions, velocity=velocities, color=colors) group = ParticleGroup() emitter(3, group) group.update(0) self.assertEqual(len(group), 3) for particle in group: self.failUnless(particle.mass in masses, (particle.mass, masses)) self.failUnless( tuple(particle.position) in positions, (particle.position, positions)) self.failUnless( tuple(particle.color) in colors, (particle.color, colors)) self.assertVector(particle.velocity, (1, 1, 0))
def test_PerParticleEmitter_template(self): from lepton import Particle, ParticleGroup from lepton.emitter import PerParticleEmitter source_group = ParticleGroup() source_group.new(Particle(position=(1, 1, 1))) source_group.new(Particle(position=(2, 2, 2))) source_group.update(0) emitter = PerParticleEmitter(source_group, rate=1, template=Particle(position=(1.0, 1.0, 1.0), velocity=(0, 5, 2), color=(0.5, 0.5, 0.5, 1.0))) group = ParticleGroup() count = emitter(1, group) group.update(0) self.assertEqual(count, len(source_group)) self.assertEqual(len(group), len(source_group)) particle = list(group)[0] self.assertVector(particle.position, (1, 1, 1)) self.assertVector(particle.velocity, (0, 5, 2)) self.assertColor(particle.color, (0.5, 0.5, 0.5, 1.0)) particle = list(group)[1] self.assertVector(particle.position, (2, 2, 2)) self.assertVector(particle.velocity, (0, 5, 2)) self.assertColor(particle.color, (0.5, 0.5, 0.5, 1.0))
def _make_group(self): from lepton import Particle, ParticleGroup g = ParticleGroup() g.new(Particle((0, 0, 0), (0, 0, 0))) g.new(Particle((0, 0, 0), (1, 1, 1), size=(2, 2, 2))) g.new(Particle((1, 1, 1), (-2, -2, -2), size=(3, 2, 0))) g.update(0) return g
def _make_group(self): from lepton import Particle, ParticleGroup g = ParticleGroup() g.new(Particle((0,0,0), (0,0,0))) g.new(Particle((0,0,0), (1,1,1), size=(2,2,2))) g.new(Particle((1,1,1), (-2,-2,-2), size=(3,2,0))) g.update(0) return g
def _make_group(self): from lepton import Particle, ParticleGroup g = ParticleGroup() g.new(Particle(position=(0, 1.0, 0), velocity=(0, 0, 0))), g.new(Particle(position=(0, 0, 1.0), velocity=(0, 0, 0))), g.update(0) p = list(g) p[0].position = (10.0, 0, 0) p[1].position = (0, 0.0, 10.0) return g
def test_PerParticleEmitter_emit_empty_source(self): from lepton import ParticleGroup from lepton.emitter import PerParticleEmitter emitter = PerParticleEmitter(ParticleGroup()) group = ParticleGroup() self.assertEqual(len(group), 0) emitter.emit(10, group) group.update(0) self.assertEqual(len(group), 0)
def test_len(self): from lepton import ParticleGroup group = ParticleGroup() self.assertEqual(len(group), 0) group.new(TestParticle()) self.assertEqual(len(group), 0) group.new(TestParticle()) self.assertEqual(len(group), 0) # New particles become visible on update group.update(0) self.assertEqual(len(group), 2)
def test_StaticEmitter_partial(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter emitter = StaticEmitter(rate=1) group = ParticleGroup() # It should take four quarter second updates to emit one self.assertEqual(emitter(0.25, group), 0) self.assertEqual(emitter(0.25, group), 0) self.assertEqual(emitter(0.25, group), 0) self.assertEqual(emitter(0.25, group), 1) group.update(0) self.assertEqual(len(group), 1)
def _make_group(self): from lepton import Particle, ParticleGroup g = ParticleGroup() g.new(Particle(position=(0, 1, 0), velocity=(0, -1, 0))), g.new(Particle(position=(0, 1, 0), velocity=(0, -1.5, 0))), g.new(Particle(position=(-1, -1, 1), velocity=(2, 2, 0))), g.new(Particle(position=(1, 1, 1), velocity=(0, 1, 0))) g.update(0) p = list(g) p[0].position = (0, 0, 0) p[1].position = (0, -0.5, 0) p[2].position = (1, 1, 1) p[3].position = (1, 2, 1) return g
def test_Lifetime_controller(self): from lepton import controller, Particle, ParticleGroup g = ParticleGroup() g.new(Particle(age=0)) g.new(Particle(age=0.8)) g.new(Particle(age=1.0)) g.new(Particle(age=0.75)) lifetime = controller.Lifetime(max_age=0.75) g.update(0) lifetime(0, g) p = list(g) self.assertEqual(len(g), 2) self.assertFloatEqiv(p[0].age, 0.0) self.assertFloatEqiv(p[1].age, 0.75)
def test_StaticEmitter_emit(self): from lepton import ParticleGroup from lepton.emitter import StaticEmitter emitter = StaticEmitter() group = ParticleGroup() self.assertEqual(len(group), 0) emitter.emit(10, group) group.update(0) self.assertEqual(len(group), 10) # Negative emit value is equivilant to zero emitter.emit(-10, group) group.update(0) self.assertEqual(len(group), 10)
def test_StaticEmitter_template(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter emitter = StaticEmitter(rate=1, template=Particle( position=(1.0, 1.0, 1.0), velocity=(0, 5, 2), color=(0.5, 0.5, 0.5, 1.0))) group = ParticleGroup() count = emitter(1, group) group.update(0) self.assertEqual(count, 1) self.assertEqual(len(group), 1) particle = list(group)[0] self.assertVector(particle.position, (1,1,1)) self.assertVector(particle.velocity, (0,5,2)) self.assertColor(particle.color, (0.5, 0.5, 0.5, 1.0))
def test_StaticEmitter_template(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter emitter = StaticEmitter(rate=1, template=Particle(position=(1.0, 1.0, 1.0), velocity=(0, 5, 2), color=(0.5, 0.5, 0.5, 1.0))) group = ParticleGroup() count = emitter(1, group) group.update(0) self.assertEqual(count, 1) self.assertEqual(len(group), 1) particle = list(group)[0] self.assertVector(particle.position, (1, 1, 1)) self.assertVector(particle.velocity, (0, 5, 2)) self.assertColor(particle.color, (0.5, 0.5, 0.5, 1.0))
def test_new_particle_kwargs(self): from lepton import ParticleGroup, Particle group = ParticleGroup() self.assertEqual(len(group), 0) self.assertEqual(group.new_count(), 0) p = group.new(position=(1, -1, 2), age=2) self.assertEqual(tuple(p.position), (1, -1, 2)) self.assertEqual(p.age, 2) tmpl_p = Particle(age=3, velocity=(-1, 2, 3)) p = group.new(tmpl_p, age=5) self.assertEqual(tuple(p.velocity), (-1, 2, 3)) self.assertEqual(p.age, 5) self.assertEqual(len(group), 0) self.assertEqual(group.new_count(), 2) self.failIf(list(group)) group.update(0) # incorporate new particles self.assertEqual(len(group), 2) self.assertEqual(group.new_count(), 0)
def test_new_particle_kwargs(self): from lepton import ParticleGroup, Particle group = ParticleGroup() self.assertEqual(len(group), 0) self.assertEqual(group.new_count(), 0) p = group.new(position=(1,-1,2), age=2) self.assertEqual(tuple(p.position), (1, -1, 2)) self.assertEqual(p.age, 2) tmpl_p = Particle(age=3, velocity=(-1,2,3)) p = group.new(tmpl_p, age=5) self.assertEqual(tuple(p.velocity), (-1,2,3)) self.assertEqual(p.age, 5) self.assertEqual(len(group), 0) self.assertEqual(group.new_count(), 2) self.failIf(list(group)) group.update(0) # incorporate new particles self.assertEqual(len(group), 2) self.assertEqual(group.new_count(), 0)
def test_PerParticleEmitter_partial(self): from lepton import Particle, ParticleGroup from lepton.emitter import PerParticleEmitter source_group = ParticleGroup() source_group.new(object()) source_group.new(object()) source_group.new(object()) source_group.update(0) emitter = PerParticleEmitter(source_group, rate=1) group = ParticleGroup() # It should take four quarter second updates to emit any self.assertEqual(emitter(0.25, group), 0) self.assertEqual(emitter(0.25, group), 0) self.assertEqual(emitter(0.25, group), 0) self.assertEqual(emitter(0.25, group), len(source_group)) group.update(0) self.assertEqual(len(group), len(source_group))
def test_mass_new_particles(self): from lepton import ParticleGroup count = 12345 group = ParticleGroup() p = TestParticle() for i in xrange(count): p.mass = i newp = group.new(p) self.assertEqual(newp.mass, p.mass) group.update(0) piter = iter(group) for i in xrange(count): newp = piter.next() self.assertEqual(newp.mass, i) self.assertEqual(len(group), count) self.assertEqual(group.killed_count(), 0) self.assertRaises(StopIteration, piter.next)
def test_StaticEmitter_discrete(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter masses = (0.5, 2.0, 8.0) positions = ((1.0,1.0,1.0), (10.0,20.0,30.0), (-100.0,0.0,0.0)) velocities = ((1,1,0),) colors = ((1.0, 1.0, 1.0, 0.5), (1.0, 0, 0, 1.0), (0, 1.0, 0, 1.0)) emitter = StaticEmitter(rate=1, mass=masses, position=positions, velocity=velocities, color=colors) group = ParticleGroup() emitter(3, group) group.update(0) self.assertEqual(len(group), 3) for particle in group: self.failUnless(particle.mass in masses, (particle.mass, masses)) self.failUnless(tuple(particle.position) in positions, (particle.position, positions)) self.failUnless(tuple(particle.color) in colors, (particle.color, colors)) self.assertVector(particle.velocity, (1,1,0))
def test_modify_controllers_during_update(self): from lepton import ParticleGroup ctrl1 = TestController() ctrl2 = TestUnbindingController() ctrl4 = TestController() ctrl3 = TestBindingController(ctrl4) group = ParticleGroup(controllers=(ctrl1, ctrl2, ctrl3)) self.assertEqual(len(group.controllers), 3) self.failUnless(ctrl1 in group.controllers) self.failUnless(ctrl2 in group.controllers) self.failUnless(ctrl3 in group.controllers) self.failUnless(ctrl4 not in group.controllers) group.update(1) self.failUnless(ctrl1.group is group) self.failUnless(ctrl2.group is group) self.failUnless(ctrl3.group is group) self.failUnless(ctrl4.group is None) self.assertEqual(len(group.controllers), 3) self.failUnless(ctrl1 in group.controllers) self.failUnless(ctrl2 not in group.controllers) self.failUnless(ctrl3 in group.controllers) self.failUnless(ctrl4 in group.controllers)
def test_new_particle(self): from lepton import ParticleGroup, Particle group = ParticleGroup() self.assertEqual(len(group), 0) self.assertEqual(group.new_count(), 0) p1 = Particle(age=1) p2 = Particle(age=2) group.new(p1) self.assertEqual(len(group), 0) self.assertEqual(group.new_count(), 1) self.failIf(list(group)) group.new(p2) self.assertEqual(len(group), 0) self.assertEqual(group.new_count(), 2) self.failIf(list(group)) group.update(0) # incorporate new particles self.assertEqual(len(group), 2) self.assertEqual(group.new_count(), 0) particles = list(group) self.assertEqual(len(particles), 2) self.assertEqual(particles[0].age, 1) self.assertEqual(particles[1].age, 2) return group, particles
def test_PerParticleEmitter_time_to_live(self): from lepton import Particle, ParticleGroup from lepton.emitter import PerParticleEmitter source_group = ParticleGroup() source_group.new(object()) source_group.new(object()) source_group.new(object()) source_group.new(object()) source_group.update(0) emitter = PerParticleEmitter(source_group, rate=1, time_to_live=3.0) group = ParticleGroup(controllers=[emitter]) count = emitter(2, group) self.assertEqual(count, 2 * len(source_group)) self.assertEqual(emitter.time_to_live, 1) self.failUnless(emitter in group.controllers) count = emitter(2, group) # Since only one second remained before expiring # only one particle per should be emitted self.assertEqual(count, len(source_group)) self.assertEqual(emitter.time_to_live, 0) self.failUnless(emitter not in group.controllers)
def test_StaticEmitter_domain(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter expected = (-42, 0, 9) class TestDomain: generate_calls = 0 def generate(self): self.generate_calls += 1 return expected domain = TestDomain() emitter = StaticEmitter(rate=1, position=domain) self.assertEqual(domain.generate_calls, 0) group = ParticleGroup() count = emitter(2, group) group.update(0) self.assertEqual(count, 2) self.assertEqual(domain.generate_calls, 2) self.assertEqual(len(group), 2) for particle in group: self.assertVector(particle.position, expected)
def test_PerParticleEmitter_template(self): from lepton import Particle, ParticleGroup from lepton.emitter import PerParticleEmitter source_group = ParticleGroup() source_group.new(Particle(position=(1,1,1))) source_group.new(Particle(position=(2,2,2))) source_group.update(0) emitter = PerParticleEmitter(source_group, rate=1, template=Particle( position=(1.0, 1.0, 1.0), velocity=(0, 5, 2), color=(0.5, 0.5, 0.5, 1.0))) group = ParticleGroup() count = emitter(1, group) group.update(0) self.assertEqual(count, len(source_group)) self.assertEqual(len(group), len(source_group)) particle = list(group)[0] self.assertVector(particle.position, (1,1,1)) self.assertVector(particle.velocity, (0,5,2)) self.assertColor(particle.color, (0.5, 0.5, 0.5, 1.0)) particle = list(group)[1] self.assertVector(particle.position, (2,2,2)) self.assertVector(particle.velocity, (0,5,2)) self.assertColor(particle.color, (0.5, 0.5, 0.5, 1.0))
def test_PerParticleEmitter_emit(self): from lepton import ParticleGroup from lepton.emitter import PerParticleEmitter source_group = ParticleGroup() source_group.new(object()) source_group.new(object()) source_group.new(object()) source_group.update(0) emitter = PerParticleEmitter(source_group) group = ParticleGroup() self.assertEqual(len(group), 0) emitter.emit(10, group) group.update(0) expected = 10 * len(source_group) self.assertEqual(len(group), expected) # Negative emit value is equivilant to zero emitter.emit(-10, group) group.update(0) self.assertEqual(len(group), expected)
) # Make the bounce controller for the screen boundary run last # to ensure no particles can "escape" default_system.add_global_controller( Bounce(screen_domain, friction=0.01) ) group = ParticleGroup(renderer=PointRenderer(point_size=ball_size)) ball_emitter = StaticEmitter( position=screen_domain, deviation=Particle(velocity=(60,60,0), color=(0.3,0.3,0.3,0)), color=[(1,0,0,1), (0,1,0,1), (0,0,1,1), (1,1,0,1), (0,1,1,1), (1,1,1,1)], mass=[1], ) ball_emitter.emit(ball_count, group) group.update(0) # Kill particles inside the bumpers for p in group: for bumper in bumpers: if p.position in bumper.domain: group.kill(p) win.resize = resize win.set_visible(True) win.resize(win.width, win.height) pyglet.clock.schedule_interval(default_system.update, 1.0/30.0) #pyglet.clock.schedule_interval(lambda x: default_system.update(0.05), (1.0/5.0)) def draw_bumpers(): glPointSize(bumpers[0].domain.radius * 2 - ball_size/2.0 - 15) glColor3f(1.0, 1.0, 0)
def test_StaticEmitter_deviation(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter template = Particle(position=(1.0, 1.0, 1.0), velocity=(0, 0, 0), size=(2, 2, 2), color=(0.5, 0.5, 0.5, 1.0)) deviation = Particle(position=(0, 0, 0), velocity=(5, 10, 5), color=(1.0, 1.0, 1.0, 0)) particle_count = 12345 emitter = StaticEmitter(rate=particle_count, template=template, deviation=deviation) group = ParticleGroup() emitter(1, group) group.update(0) self.assertEqual(len(group), particle_count) position_mean = [0, 0, 0] position_var = [0, 0, 0] velocity_mean = [0, 0, 0] velocity_var = [0, 0, 0] size_mean = [0, 0, 0] size_var = [0, 0, 0] color_mean = [0, 0, 0, 0] color_var = [0, 0, 0, 0] def accum(mean_list, var_list, val, template): for i in range(len(mean_list)): mean_list[i] += val[i] d = val[i] - template[i] var_list[i] += d**2 def calc_mean_var(mean_list, var_list): for i in range(len(mean_list)): mean_list[i] /= float(particle_count) var_list[i] = math.sqrt(var_list[i] / float(particle_count)) for particle in group: accum(position_mean, position_var, particle.position, template.position) accum(velocity_mean, velocity_var, particle.velocity, template.velocity) accum(size_mean, size_var, particle.size, template.size) accum(color_mean, color_var, particle.color, template.color) calc_mean_var(position_mean, position_var) calc_mean_var(velocity_mean, velocity_var) calc_mean_var(size_mean, size_var) calc_mean_var(color_mean, color_var) self.assertVector(position_mean, template.position, tolerance=0.2) self.assertVector(position_var, deviation.position, tolerance=0.2) self.assertVector(velocity_mean, template.velocity, tolerance=0.2) self.assertVector(velocity_var, deviation.velocity, tolerance=0.2) self.assertVector(size_mean, template.size, tolerance=0.2) self.assertVector(size_var, deviation.size, tolerance=0.2) self.assertColor(color_mean, template.color, tolerance=0.2) self.assertColor(color_var, deviation.color, tolerance=0.2)
Drag(0.0, 0.0001, (200, 400, 0), domain=right_fan), *[bumper.controller for bumper in bumpers]) # Make the bounce controller for the screen boundary run last # to ensure no particles can "escape" default_system.add_global_controller(Bounce(screen_domain, friction=0.01)) group = ParticleGroup(renderer=PointRenderer(point_size=ball_size)) ball_emitter = StaticEmitter( position=screen_domain, deviation=Particle(velocity=(60, 60, 0), color=(0.3, 0.3, 0.3, 0)), color=[(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1), (1, 1, 0, 1), (0, 1, 1, 1), (1, 1, 1, 1)], mass=[1], ) ball_emitter.emit(ball_count, group) group.update(0) # Kill particles inside the bumpers for p in group: for bumper in bumpers: if p.position in bumper.domain: group.kill(p) win.resize = resize win.set_visible(True) win.resize(win.width, win.height) pyglet.clock.schedule_interval(default_system.update, 1.0 / 30.0) #pyglet.clock.schedule_interval(lambda x: default_system.update(0.05), (1.0/5.0)) def draw_bumpers(): glPointSize(bumpers[0].domain.radius * 2 - ball_size / 2.0 - 15)
def test_StaticEmitter_deviation(self): from lepton import Particle, ParticleGroup from lepton.emitter import StaticEmitter template=Particle( position=(1.0, 1.0, 1.0), velocity=(0, 0, 0), size=(2,2,2), color=(0.5, 0.5, 0.5, 1.0)) deviation=Particle( position=(0, 0, 0), velocity=(5, 10, 5), color=(1.0, 1.0, 1.0, 0)) particle_count = 12345 emitter = StaticEmitter( rate=particle_count, template=template, deviation=deviation) group = ParticleGroup() emitter(1, group) group.update(0) self.assertEqual(len(group), particle_count) position_mean =[0,0,0] position_var = [0,0,0] velocity_mean = [0,0,0] velocity_var = [0,0,0] size_mean = [0,0,0] size_var = [0,0,0] color_mean = [0,0,0,0] color_var = [0,0,0,0] def accum(mean_list, var_list, val, template): for i in range(len(mean_list)): mean_list[i] += val[i] d = val[i] - template[i] var_list[i] += d**2 def calc_mean_var(mean_list, var_list): for i in range(len(mean_list)): mean_list[i] /= float(particle_count) var_list[i] = math.sqrt(var_list[i] / float(particle_count)) for particle in group: accum(position_mean, position_var, particle.position, template.position) accum(velocity_mean, velocity_var, particle.velocity, template.velocity) accum(size_mean, size_var, particle.size, template.size) accum(color_mean, color_var, particle.color, template.color) calc_mean_var(position_mean, position_var) calc_mean_var(velocity_mean, velocity_var) calc_mean_var(size_mean, size_var) calc_mean_var(color_mean, color_var) self.assertVector(position_mean, template.position, tolerance=0.2) self.assertVector(position_var, deviation.position, tolerance=0.2) self.assertVector(velocity_mean, template.velocity, tolerance=0.2) self.assertVector(velocity_var, deviation.velocity, tolerance=0.2) self.assertVector(size_mean, template.size, tolerance=0.2) self.assertVector(size_var, deviation.size, tolerance=0.2) self.assertColor(color_mean, template.color, tolerance=0.2) self.assertColor(color_var, deviation.color, tolerance=0.2)