カオス的挙動をBlenderのpythonスクリプトで作成
Blenderシリーズ第3段はカオス的挙動に挑戦してみました。
カオス的挙動
Blenderでは簡単に力場を設定できるので、もしかしたら簡単にカオス的挙動が作れるのではと思い実際にやってみました。
結果は最後に動画を載せておきますが、それっぽい動きをしてくれました。
序盤でポテンシャルの谷に捕まったかと思いきや、抜け出して全く違う方向に進むのが良い感じです。
結果が面白かったので力場の値を強くしましたが、動きが速すぎるのがちょっと残念でした。
もちろん力場の値を弱くしてもそれっぽい動きはしてくれます。
5つ設定した力場の内、真ん中が斥力、他の4つが引力に設定されています。
pythonスクリプト
下記が実際に使用したpythonスクリプトです。
玉と球形の土台を用意して、5つの力場を設定するだけです。
力場を設定するときになぜかbpy.ops.object.forcefield_toggle()を2回呼ぶ必要があったので注意して下さい。
pythonファイルの使用方法は以前の記事を参考にして下さい。
Blenderのバージョンは剛体シミュレーションが簡単になった2.66以上をお使い下さい。
# -*- coding: utf-8 -*- import os import bpy import math # 球を作成 (ブーリアンで使用した後、シミュレーションで使用) bpy.ops.mesh.primitive_uv_sphere_add( location = ( 0, 0, 1 ) ) sphere = bpy.data.objects["Sphere"] bpy.ops.object.shade_smooth() # 球を後々の為に動的オブジェクトに指定しておく bpy.ops.rigidbody.object_add() sphere.rigid_body.mass = 0.1 sphere.rigid_body.friction = 0.0 # デフォルトで存在する立方体から球をブーリアンで引く cube = bpy.data.objects["Cube"] bpy.context.scene.objects.active = cube bpy.ops.object.shade_smooth() bpy.ops.object.modifier_add( type = 'BOOLEAN' ) cube.modifiers["Boolean"].operation = 'DIFFERENCE' cube.modifiers["Boolean"].object = sphere bpy.ops.object.modifier_apply( modifier = "Boolean" ) # 立方体を静的オブジェクトに指定 bpy.ops.rigidbody.object_add( type='PASSIVE' ) cube.rigid_body.friction = 0.0 # 球を転がす用のサイズに変更 sphere.location = ( 0.9, 0, 1 ) sphere.scale = ( 0.1, 0.1, 0.1 ) # 5つの空のオブジェクトを配置 bpy.ops.object.empty_add(type = 'SPHERE', location = (0, 0, 0 )) empty0 = bpy.data.objects["Empty"] bpy.ops.object.empty_add(type = 'SPHERE', location = (0.7, 0, 0 )) empty1 = bpy.data.objects["Empty.001"] bpy.ops.object.empty_add(type = 'SPHERE', location = (0, 0.7, 0 )) empty2 = bpy.data.objects["Empty.002"] bpy.ops.object.empty_add(type = 'SPHERE', location = (-0.7, 0, 0 )) empty3 = bpy.data.objects["Empty.003"] bpy.ops.object.empty_add(type = 'SPHERE', location = (0, -0.7, 0 )) empty4 = bpy.data.objects["Empty.004"] empty = [empty0, empty1, empty2, empty3, empty4] # 空のオブジェクトに力場を設定。なぜかforcefield_toggle()を2回呼ぶ必要がある for e in empty: bpy.context.scene.objects.active = e bpy.ops.object.forcefield_toggle() bpy.ops.object.forcefield_toggle() e.field.strength = -300 empty0.field.strength = 250 # カメラ bpy.data.objects["Camera"].location = ( 2, 2, 5 ) bpy.data.objects["Camera"].rotation_euler = ( math.pi/6, 0, math.pi*3/4 ) bpy.data.cameras["Camera"].lens = 30 # 照明 bpy.data.objects["Lamp"].location = (0, 1, 10) bpy.data.objects["Lamp"].rotation_euler = ( -math.pi/60, -math.pi/120, math.pi/12 ) bpy.data.lamps["Lamp"].type = 'SUN' # 物理シミュレーション bpy.ops.ptcache.bake_all() # 動画作成 bpy.context.scene.render.resolution_x = 400 bpy.context.scene.render.resolution_y = 300 bpy.context.scene.render.resolution_percentage = 100 bpy.context.scene.render.image_settings.file_format = 'AVI_JPEG' bpy.data.scenes["Scene"].render.filepath = "test.avi" bpy.context.scene.frame_start = 0 bpy.context.scene.frame_end = 250 bpy.ops.render.render(animation=True) # 保存 savePath = os.path.abspath(os.path.dirname(__file__)) bpy.path.relpath(savePath) bpy.ops.wm.save_as_mainfile(filepath="test.blend", relative_remap=True)