Last active
August 23, 2020 06:30
-
-
Save ricardocchaves/789c377c0ef3330066a9e2444d3bf2a2 to your computer and use it in GitHub Desktop.
Blender - An empty acts as a "force field" towards a group of objects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bpy | |
import mathutils | |
from random import randint | |
def my_handler(scene): | |
# I couldn't register a class as handler or use global variables | |
# so I'm using hidden empties as global variables to store the | |
# previous positions when required. | |
old_loc_name = "old_empty" | |
if old_loc_name not in bpy.data.objects: | |
print("Creating new") | |
o = bpy.data.objects.new(old_loc_name,None) | |
# Uncomment if you want the empty to appear | |
# in your scene manager. By default it's commented | |
# to prevent it from becoming too cluttered. | |
#bpy.context.scene.collection.objects.link(o) | |
old_loc = bpy.data.objects[old_loc_name].location | |
target = bpy.data.objects["Empty"].location # Get target's location | |
bpy.data.objects[old_loc_name].location = target | |
# Empty position changed | |
# Check cubes to update them | |
distance = 5 | |
move_inc = 0.3 | |
noise_factor = 0.4 | |
# Noise vector | |
noise_vec = mathutils.Vector((randint(-1000,1000)/1000,randint(-1000,1000)/1000,randint(-1000,1000)/1000))*1 | |
# Affects every object that is a MESH and has 'Cube' in the name | |
for cube in [x for x in bpy.data.objects if 'Cube' in x.name and x.type=="MESH"]: | |
t_vec = cube.location-target | |
origin_name = cube.name+"_origin" | |
# Get the original position of this cube | |
# or create a new empty for it if it doesn't already exist | |
if origin_name not in bpy.data.objects: | |
o = bpy.data.objects.new(origin_name,None) | |
o.location = cube.location | |
# Uncomment if you want the empty to appear | |
# in your scene manager. By default it's commented | |
# to prevent it from becoming too cluttered. | |
#bpy.context.scene.collection.objects.link(o) | |
else: | |
o = bpy.data.objects[origin_name] | |
o_vec = cube.location-o.location | |
# If cube is in range of target, move to the opposite direction | |
# else try to return to origins | |
if t_vec.length < distance: | |
t_vec_n = mathutils.Vector.normalized(t_vec) | |
# Noise shift | |
n_vec = (mathutils.Vector.orthogonal(t_vec_n)+noise_vec)*noise_factor | |
cube.location += t_vec_n*move_inc+n_vec | |
else: | |
if o_vec.length > move_inc: | |
o_vec_n = -mathutils.Vector.normalized(o_vec)*move_inc | |
cube.location += o_vec_n | |
# Uncomment this if you need to clear every the cube's origins | |
""" | |
for o in bpy.data.objects: | |
if '_origin' in o.name: | |
bpy.data.objects.remove(o) | |
""" | |
bpy.app.handlers.frame_change_pre.clear() | |
bpy.app.handlers.frame_change_pre.append(my_handler) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment