For an art project we’ve been working on, I’d still like to add a flock of birds. We have yet to accomplish this.
This is a Cycles render.
Basically it’s a low poly breathing landscape where as a user (player) you can make it breathe deeper (input now is either a joystick or keyboard, later we’ll use an Arduino to make the input real breathing using a mic or other sensor).
Few months ago I posted a thread seeking help on a similar issue (the dispersion of the trees, while keeping their animation), yet I solved it differently by simply converting particles to objects (meshes) then joining the meshes with the landscape.
While the boids system, available for regular animations, seems perfect, I’m unable to implement it to the Game Engine.
I couldn’t find a way to convert animated particles (duplicated objects, or rather groups in my case) to regular animated meshes until I found the script below.
While a true boids system would be more convenient - as there could even be interaction with the environment - just an animated flock flying around at a safe distance without interacting would be just as fine. Hence I was glad to find this script that will convert a particle system to animated meshes.
import bpy
# Set these to False if you don't want to key that property.
KEYFRAME_LOCATION = True
KEYFRAME_ROTATION = True
KEYFRAME_SCALE = True
KEYFRAME_VISIBILITY = True # Viewport and render visibility.
def create_objects_for_particles(ps, obj):
# Duplicate the given object for every particle and return the duplicates.
# Use instances instead of full copies.
obj_list = []
mesh = obj.data
for i, _ in enumerate(ps.particles):
dupli = bpy.data.objects.new(
name="particle.{:03d}".format(i),
object_data=mesh)
bpy.context.scene.objects.link(dupli)
obj_list.append(dupli)
return obj_list
def match_and_keyframe_objects(ps, obj_list, start_frame, end_frame):
# Match and keyframe the objects to the particles for every frame in the
# given range.
for frame in range(start_frame, end_frame + 1):
bpy.context.scene.frame_set(frame)
for p, obj in zip(ps.particles, obj_list):
match_object_to_particle(p, obj)
keyframe_obj(obj)
def match_object_to_particle(p, obj):
# Match the location, rotation, scale and visibility of the object to
# the particle.
loc = p.location
rot = p.rotation
size = p.size
if p.alive_state == 'ALIVE':
vis = True
else:
vis = False
obj.location = loc
# Set rotation mode to quaternion to match particle rotation.
obj.rotation_mode = 'QUATERNION'
obj.rotation_quaternion = rot
obj.scale = (size, size, size)
obj.hide = not(vis)
obj.hide_render = not(vis)
def keyframe_obj(obj):
# Keyframe location, rotation, scale and visibility if specified.
if KEYFRAME_LOCATION:
obj.keyframe_insert("location")
if KEYFRAME_ROTATION:
obj.keyframe_insert("rotation_quaternion")
if KEYFRAME_SCALE:
obj.keyframe_insert("scale")
if KEYFRAME_VISIBILITY:
obj.keyframe_insert("hide")
obj.keyframe_insert("hide_render")
def main():
# Assume only 2 objects are selected.
# The active object should be the one with the particle system.
ps_obj = bpy.context.object
obj = [obj for obj in bpy.context.selected_objects if obj != ps_obj][0]
ps = ps_obj.particle_systems[0] # Assume only 1 particle system is present.
start_frame = bpy.context.scene.frame_start
end_frame = bpy.context.scene.frame_end
obj_list = create_objects_for_particles(ps, obj)
match_and_keyframe_objects(ps, obj_list, start_frame, end_frame)
if __name__ == '__main__': main()
When applying this script to my birds, they stop ‘living’, they lose their wing movement. Because I’m using a group of three birds animated with an armature.
Next problem is also that I’d have to assign each mesh an action Actuator. Going through all boids separately seems a tedious job, almost undoable; so I’m looking for a way to automatically add the animation to the game engine. (just friggin’ add the boids to the game engine, aargh …)
So either I’m looking for ways to enhance this script or completely new ways of thinking. I also thought of using an animated texture (video). I also tried to create a flock using the seek actuator, but that really looked bad.
Want clarification or the file we’re working on? More than glad to share …