Blenderドミノ(その4)

倒れた時に違った色が見えるように、ドミノ牌の各面の色を変えてみます。

起動時のCubeの各面に色を付けていきます。
まずは色を揃えます。

>>> red=(1,0,0)
>>> yellow=(1,1,0)
>>> green=(0,1,0)
>>> blue=(0,0,1)
>>> white=(1,1,1)
>>> orange=(0.8,0.3,0)
>>> colorlist=[red,yellow,orange,blue,white,green]

「Blenderでルービックキューブ(その1)」で使った色と同じ色を使いました。立方体なので6面の6色です。

「Blenderマテリアル」でやったように、各面にさきほど作った色を割り当てます。

>>> import bmesh
>>> bpy.ops.object.mode_set(mode='EDIT')
{'FINISHED'}

>>> bm=bmesh.from_edit_mesh(bpy.context.object.data)
>>> i=1
>>> for f in bm.faces:
...     m=bpy.data.materials.new("Material.%03d" % i)
...     m.diffuse_color=colorlist.pop(0)
...     bpy.context.object.data.materials.append(m)
...     f.material_index = i
...     i = i + 1
...

向かって左側が正面で、bm.facesリストの第一要素(faces[0])の底面から、colorlistの第一要素のredが割り当てられ、順にfaces[1]~faces[5]まで割り当てます。

次は、Cubeの形をドミノ牌の形にします。

>>> bpy.ops.object.mode_set(mode='OBJECT')
{'FINISHED'}

>>> bpy.ops.transform.resize(value=(0.5, 0.17, 1))
{'FINISHED'}

>>> bpy.ops.transform.translate(value=(0,0,1))
{'FINISHED'}

>>> bpy.ops.rigidbody.object_add(type='ACTIVE')
{'FINISHED'}

「Blenderドミノ(その2)」で使った計算式です。渦巻き状に牌が並びます。

>>> import math
>>> r=60
>>> for i in range(60,300):
...     inc_r=720/i
...     rad_r=math.radians(r)
...     x=math.log2(i)/math.sqrt(i)*2 * math.cos(rad_r)
...     y=math.log2(i)/math.sqrt(i)*2 * math.sin(rad_r)
...     bpy.ops.object.duplicate()
...     bpy.ops.transform.translate(value=(x,y,0))
...     bpy.ops.transform.rotate(value=math.radians(inc_r),axis=(0,0,1))
...     r=r+inc_r

ドミノ倒しのアニメーションをさせるため、ここでキーフレームを設定しておきます。

>>> bpy.context.scene.frame_set(1)
>>> bpy.context.active_object.keyframe_insert(data_path="rotation_euler",index=-1)
True

>>> bpy.context.active_object.keyframe_insert(data_path="location",index=-1)
True

最初に倒すドミノ牌を、回転させます。
CubeのORIGINがCubeの中心に設定されているため、rotateさせても中心で回転するため、
倒れたように見えません。
一旦ORIGINをCubeの底に設定してから、roteteさせることにします。

>>> pos=bpy.context.object.location
>>> bpy.context.scene.cursor_location=(pos.x, pos.y, pos.z-1)
>>> bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
>>> bpy.ops.transform.rotate(value=1,axis=(0.5, 1, 0),constraint_axis=(True,True,True))
>>> bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')

フレーム10ぐらいで、キーフレームを設定しておきます。

>>> bpy.context.scene.frame_set(10)
>>> bpy.context.active_object.keyframe_insert(data_path="rotation_euler",index=-1)
>>> bpy.context.active_object.keyframe_insert(data_path="location",index=-1)

最後に床を作ります。Planeを追加し拡大したら、PASSIVEの剛体に設定します。

bpy.context.scene.cursor_location=(0,0,0)
bpy.ops.mesh.primitive_plane_add()
bpy.ops.transform.resize(value=(77,77,1))
bpy.ops.rigidbody.object_add(type='PASSIVE')

全部通してスクリプトを見てみましょう。

import bpy,bmesh,math

red=(1,0,0)
yellow=(1,1,0)
green=(0,1,0)
blue=(0,0,1)
white=(1,1,1)
orange=(0.8,0.3,0)

colorlist=[red,yellow,orange,blue,white,green]

bpy.ops.object.mode_set(mode='EDIT')
bm=bmesh.from_edit_mesh(bpy.context.object.data)

i=1
for f in bm.faces:
	m=bpy.data.materials.new("Material.%03d" % i)
	m.diffuse_color=colorlist.pop(0)
	bpy.context.object.data.materials.append(m)
	f.material_index = i
	i = i + 1

bpy.ops.object.mode_set(mode='OBJECT')

bpy.ops.transform.resize(value=(0.5, 0.17, 1))
bpy.ops.transform.translate(value=(0,0,1))
bpy.ops.rigidbody.object_add(type='ACTIVE')

r=60

for i in range(60,300):
    inc_r=720/i
    rad_r=math.radians(r)
    x=math.log2(i)/math.sqrt(i)*2 * math.cos(rad_r)
    y=math.log2(i)/math.sqrt(i)*2 * math.sin(rad_r)
    bpy.ops.object.duplicate()
    bpy.ops.transform.translate(value=(x,y,0))
    bpy.ops.transform.rotate(value=math.radians(inc_r),axis=(0,0,1))
    r=r+inc_r

bpy.context.scene.frame_set(1)
bpy.context.active_object.keyframe_insert(data_path="rotation_euler",index=-1)
bpy.context.active_object.keyframe_insert(data_path="location",index=-1)

pos=bpy.context.object.location

bpy.context.scene.cursor_location=(pos.x, pos.y, pos.z-1)

bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
bpy.ops.transform.rotate(value=1,axis=(0.5, 1, 0),constraint_axis=(True,True,True))

bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')

bpy.context.scene.frame_set(10)
bpy.context.active_object.keyframe_insert(data_path="rotation_euler",index=-1)
bpy.context.active_object.keyframe_insert(data_path="location",index=-1)

bpy.context.scene.cursor_location=(0,0,0)
bpy.ops.mesh.primitive_plane_add()
bpy.ops.transform.resize(value=(77,77,1))
bpy.ops.rigidbody.object_add(type='PASSIVE')

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA