映画『神さまの言うとおり』(2014)
ほんと怖すぎです。イケメンが出てくるからって安心しないでください。(R15+)で、スプラッターなので視聴に注意が必要です。
楽しいゲームがたくさん用意されているのですが、そのゲームに負けてしまうとデス! つまり生き残ることができないのですが、ほとんどの高校生が失敗して果てます。男子も、女子も、美男子でも、美少女でも、差別なく酷いことされます。
私は初めて試聴したときは、ダルマのシーンでリタイヤして、続きを見ないままレンタルへ返却しました。当時ダルマが怖くて眠れなくなりそうだったので、怖くないダルマをBlenderでPythonプログラミングしてみようと思い、本記事を書いた次第です。
さて怖くないダルマを使って、Blenderでダルマ落としをチャレンジしてみます。
Contents
1. ダルマのマッピング画像を準備する
ダルマ画像としてこのように塗り絵を作りました。
2. z方向の重力を大きくする
重力が小さいままだと、ダルマが浮き上がってしまいますので、大きい数字(マイナス)にします。
bpy.data.scenes["Scene"].gravity.z=-50
3. 最初からあるCubeを地面に変形する
Cubeを変形して地面にしたら、PASSIVEタイプの剛体にします。
bpy.data.objects['Cube'].location=(0,0,-2) bpy.ops.transform.resize(value=(9,9,1)) bpy.ops.rigidbody.object_add(type='PASSIVE')
4. 新規に円柱を追加してダルマにする
円柱を追加したら、UVマッピング用の切れ込みを入れます。
bpy.ops.mesh.primitive_cylinder_add() bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_mode(type='EDGE') mesh=bmesh.from_edit_mesh(bpy.context.object.data) bpy.ops.mesh.select_all(action='DESELECT') mesh.edges[0].select = True for i in range(0,32): mesh.edges[i*3+1].select = True mesh.edges[i*3+2].select = True bpy.context.scene.objects.active = bpy.context.scene.objects.active bpy.ops.mesh.mark_seam() mat=bpy.data.materials.new('Material.001') mat.emit=1 tex1 = bpy.data.textures.new('Tex1', type='IMAGE') fname=os.path.expanduser('~/dharma.png') tex1.image = bpy.data.images.load(fname) bpy.context.object.data.materials.append(mat) mt=mat.texture_slots.add() mat.texture_slots[0].texture=tex1 mt.texture_coords='OBJECT' bpy.data.materials['Material.001'].texture_slots[0].texture = tex1 bpy.data.materials['Material.001'].texture_slots[0].texture_coords='UV' bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.unwrap()
5. ダルマを剛体にする
ダルマをACTIVEタイプの剛体にします。一番下のダルマが飛ばされたときに、上のダルマが真下に落ちるように細かい設定をします。
bpy.ops.rigidbody.object_add(type='ACTIVE') cy.rigid_body.use_deactivation=True cy.rigid_body.use_start_deactivated=True cy.rigid_body.collision_shape="CYLINDER" cy.rigid_body.use_margin=True cy.rigid_body.collision_margin=1
6. ダルマをコピーして増やす
ダルマをコピーしていきます。スクリプトの見せ場ですね。
for i in range(0,100): bpy.ops.object.duplicate() bpy.ops.transform.translate(value=(0,0,2))
7. ダルマ落とし用ハンマーを作る
ダルマ落とし用ハンマーっていっても、ただの床にくっついている四角い棒です。
Cubeを追加して、細長くします。ACTIVEタイプの剛体にしますが、collision_shapeをMESH型にしないと、なぜかダルマをすり抜けることがあります。
bpy.ops.mesh.primitive_cube_add() bpy.ops.transform.resize(value=(9, 0.2, 1)) bpy.ops.rigidbody.object_add(type='ACTIVE') bpy.data.objects['Cube.001'].rigid_body.kinematic=True bpy.data.objects["Cube.001"].rigid_body.collision_shape="MESH"
8. フレームを設定して、ハンマーを往復移動させる
フレーム番号を設定したら、ハンマーを所定の場所に移動させ、キーフレームを設定します。
往復するために方向(direction)が交互に変わります。
direction=-1 for i in range(1,10): bpy.context.scene.frame_set(i*20) bpy.ops.transform.translate(value=(0,direction*18,0)) bpy.context.active_object.keyframe_insert(data_path="location", index=-1) direction= -direction
9. 完成スクリプト
全部を通したスクリプトはこれです。
~$ cat dharma.sh #!/bin/bash cat <<EOL>/tmp/tmp.py import bpy,bmesh,math,os bpy.data.scenes["Scene"].gravity.z=-50 bpy.data.objects['Cube'].location=(0,0,-2) bpy.ops.transform.resize(value=(9,9,1)) bpy.ops.rigidbody.object_add(type='PASSIVE') bpy.ops.mesh.primitive_cylinder_add() bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_mode(type='EDGE') mesh=bmesh.from_edit_mesh(bpy.context.object.data) bpy.ops.mesh.select_all(action='DESELECT') mesh.edges[0].select = True for i in range(0,32): mesh.edges[i*3+1].select = True mesh.edges[i*3+2].select = True bpy.context.scene.objects.active = bpy.context.scene.objects.active bpy.ops.mesh.mark_seam() mat=bpy.data.materials.new('Material.001') mat.emit=1 tex1 = bpy.data.textures.new('Tex1', type='IMAGE') fname=os.path.expanduser('~/dharma.png') tex1.image = bpy.data.images.load(fname) bpy.context.object.data.materials.append(mat) mt=mat.texture_slots.add() mat.texture_slots[0].texture=tex1 mt.texture_coords='OBJECT' bpy.data.materials['Material.001'].texture_slots[0].texture = tex1 bpy.data.materials['Material.001'].texture_slots[0].texture_coords='UV' bpy.ops.mesh.select_all(action='SELECT') bpy.ops.uv.unwrap() cy=bpy.data.objects['Cylinder'] cy.rotation_mode='XYZ' cy.rotation_euler=(0, 0, math.pi/2) bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.rigidbody.object_add(type='ACTIVE') cy.rigid_body.use_deactivation=True cy.rigid_body.use_start_deactivated=True cy.rigid_body.collision_shape="CYLINDER" cy.rigid_body.use_margin=True cy.rigid_body.collision_margin=1 for i in range(0,100): bpy.ops.object.duplicate() bpy.ops.transform.translate(value=(0,0,2)) bpy.ops.mesh.primitive_cube_add() bpy.ops.transform.resize(value=(9, 0.2, 1)) bpy.ops.rigidbody.object_add(type='ACTIVE') bpy.data.objects['Cube.001'].rigid_body.kinematic=True bpy.data.objects["Cube.001"].rigid_body.collision_shape="MESH" bpy.context.scene.frame_set(1) bpy.ops.transform.translate(value=(0,9,0)) bpy.context.active_object.keyframe_insert(data_path="location", index=-1) direction=-1 for i in range(1,10): bpy.context.scene.frame_set(i*20) bpy.ops.transform.translate(value=(0,direction*18,0)) bpy.context.active_object.keyframe_insert(data_path="location", index=-1) direction= -direction bpy.context.scene.frame_set(1) bpy.data.objects['Camera'].location=(10,-9,10) bpy.data.objects['Lamp'].location=(3,-4,5) bpy.data.lamps['Lamp'].distance=2000 EOL blender -b -P /tmp/tmp.py -o //test -a -F PNG -x 1 -f 1 | grep ^Save convert -layers optimize -loop 0 -delay 5 test????.png test.gif
10. 実行すると
上のスクリプトを実行すると、このようなGIFアニメができます。
見事にダルマ落としチャレンジ失敗しました。
あれから本映画を最後まで試聴してみましたが、やはり怖いものは怖いです。
本記事のダルマ落とし失敗の動画を見て気を紛らわしました。
コメント