fixed particle life

This commit is contained in:
ryanontheinstide
2024-08-17 12:29:26 -04:00
parent d104b92e08
commit d05fac0f30
+16 -19
View File
@@ -241,13 +241,15 @@ class ParticleSystemMaskBase(MaskBase, ABC):
def __init__(self):
super().__init__()
self.initialize()
self.total_time = 0
def initialize(self):
self.space = pymunk.Space()
self.space.gravity = pymunk.Vec2d(0, 0)
self.particles: List[pymunk.Body] = []
self.mask_shapes: List[pymunk.Shape] = []
self.particles_to_emit = [] # List of fractional particle counts for each emitter
self.particles_to_emit = []
self.total_particles_emitted = 0
self.max_particles = 0
self.emitters = []
@@ -255,6 +257,7 @@ class ParticleSystemMaskBase(MaskBase, ABC):
self.spring_joints = []
self.static_bodies = []
self.vortices = []
self.total_time = 0
@abstractmethod
def process_single_mask(self, mask: np.ndarray, frame_index: int, **kwargs) -> Tuple[np.ndarray, np.ndarray]:
@@ -391,9 +394,7 @@ class ParticleSystemMaskBase(MaskBase, ABC):
total_force = tangential_force + radial_force
# Apply the force to the particle instead of directly modifying its velocity
particle.apply_force_at_local_point(total_force)
# print(f"Applied vortex force: {total_force} to particle at {particle.position}")
def setup_spring_joints(self):
for emitter_index, emitter in enumerate(self.emitters):
@@ -440,7 +441,6 @@ class ParticleSystemMaskBase(MaskBase, ABC):
force_direction = -force_direction
force = force_direction * force_magnitude
particle.apply_force_at_world_point(force, particle.position)
# print(f"Applied gravity well force: {force} to particle at {particle.position}")
def initialize_static_bodies(self, width, height, static_bodies):
pass
@@ -515,6 +515,7 @@ class ParticleSystemMaskBase(MaskBase, ABC):
###END FORCES AND SHIT
def update_particle_system(self, dt: float, current_mask: np.ndarray, respect_mask_boundary: bool):
self.total_time += dt
if respect_mask_boundary:
self.update_mask_boundary(current_mask)
@@ -524,14 +525,19 @@ class ParticleSystemMaskBase(MaskBase, ABC):
sub_dt = dt / sub_steps
for _ in range(sub_steps):
# Emit new particles from each emitter
for i, emitter in enumerate(self.emitters):
self.particles_to_emit[i] += emitter['emission_rate'] * sub_dt
emission_rate = emitter['emission_rate'] * 10 # Increased sensitivity
self.particles_to_emit[i] += emission_rate * sub_dt
while self.particles_to_emit[i] >= 1 and self.total_particles_emitted < self.max_particles:
self.emit_particle(emitter, height, width, i)
self.particles_to_emit[i] -= 1
# Update particle positions
particles_before = len(self.particles)
self.particles = [p for p in self.particles if self.total_time - p.creation_time < p.lifetime]
particles_after = len(self.particles)
particles_removed = particles_before - particles_after
for particle in self.particles:
self.apply_vortex_force(particle, sub_dt)
self.apply_gravity_well_force(particle)
@@ -541,27 +547,20 @@ class ParticleSystemMaskBase(MaskBase, ABC):
self.check_particle_mask_collision(particle, old_pos, new_pos)
particle.position = new_pos
self.space.step(sub_dt)
# Setup spring joints after emitting new particles
self.setup_spring_joints()
current_time = self.space.current_time_step
self.particles = [p for p in self.particles if current_time - p.creation_time < p.lifetime]
def check_particle_mask_collision(self, particle, old_pos, new_pos):
for segment in self.mask_shapes:
if self.line_segment_intersect(old_pos, new_pos, pymunk.Vec2d(*segment.a), pymunk.Vec2d(*segment.b)):
segment_vec = pymunk.Vec2d(*segment.b) - pymunk.Vec2d(*segment.a)
normal = segment_vec.perpendicular_normal()
# Reflect velocity
v = particle.velocity
reflection = v - 2 * v.dot(normal) * normal
particle.velocity = reflection * 0.9 # Reduce velocity slightly on bounce
# Move particle out of the boundary
penetration_depth = (new_pos - old_pos).dot(normal)
particle.position = old_pos + normal * (penetration_depth + particle.size / 2 + 1)
break
@@ -589,11 +588,11 @@ class ParticleSystemMaskBase(MaskBase, ABC):
particle = pymunk.Body(mass, moment)
particle.position = emitter_pos
particle.velocity = velocity
particle.creation_time = self.space.current_time_step
particle.creation_time = self.total_time
particle.lifetime = self.particle_lifetime
particle.size = particle_size
particle.color = emitter['color']
particle.emitter_index = emitter_index # Store the emitter index
particle.emitter_index = emitter_index
shape = pymunk.Circle(particle, radius)
shape.elasticity = 0.9
@@ -669,11 +668,9 @@ class ParticleSystemMaskBase(MaskBase, ABC):
# Update emitter position
emitter['position'] = (emitter['emitter_x'] * width, emitter['emitter_y'] * height)
#print(f"Frame {frame_index}, t={t:.2f}s, Emitter modulated: {emitter}")
def main_function(self, masks, strength, invert, subtract_original, grow_with_blur, emitters, **kwargs):
self.initialize()
# Add initial x and y positions for each emitter
for emitter in emitters:
emitter['initial_x'] = emitter['emitter_x']
emitter['initial_y'] = emitter['emitter_y']