オブジェクトのコマを抜く[.blend]
ついったにオブジェクトのコマ抜きのお話しが流れてきました。
背景はフルコマで動いて、主要なオブジェクトはコマを抜いてアニメーションする。
これは(題材として)面白そうね。
都度親子関係付けて、キーフレームベイクすればプレビューでいけんじゃね?っていうことで。
あっ、なんかできたっぽい。(めちゃめちゃ試行錯誤しましたけど)
コマ抜いた方。終わりの方のコマ、GIF最適化がうまくいってないですけどまあそれはご愛嬌。
POCコード
POC、出来るかどうか確認の為のコードですので本来必要なエラーハンドリングとか無いです。
m の値を適当に変えておいて、スクリプト実行、対象オブジェクトにコンストレイント設定するだけ。元の動きに戻すのもコンストレイント外すだけ。簡単。ページからダウンロードできる .blendファイルにも入れときました。
# (POC) skip frames
#
# 1. select target object , and camera
# 2. run script
# 3. set constraints to target object (manually)
# copy location -> new_obj
# copy rotation -> new_obj
# 4. play animation
# 5. yaay!!
#
import bpy
import mathutils
m = 4
scene = bpy.context.scene
layer = bpy.context.view_layer
act_obj = bpy.context.object
sel_objs = bpy.context.selected_objects
src_obj = None
if act_obj.type == 'CAMERA':
l = len(sel_objs)
if l == 2:
for x in sel_objs:
if x != act_obj:
src_obj = x
if src_obj != None:
new_obj = bpy.data.objects.new('new_obj', None)
scene.collection.objects.link( new_obj )
tmp_obj = bpy.data.objects.new('tmp_obj', None)
scene.collection.objects.link( tmp_obj )
c = 0
src_obj.select_set(False)
tmp_obj.select_set(True)
for x in range( scene.frame_start, scene.frame_end):
scene.frame_set(x)
if (c % m ) == 0:
if tmp_obj.parent != None:
bpy.ops.object.parent_clear(type='CLEAR')
tmp_obj.location = src_obj.location
tmp_obj.rotation_euler = src_obj.rotation_euler
bpy.ops.object.parent_set(type='OBJECT', keep_transform=False)
layer.update()
loc , rot, sca = tmp_obj.matrix_world.decompose()
print(rot)
new_obj.location = loc
new_obj.rotation_euler = rot.to_euler()
new_obj.keyframe_insert(data_path='location', frame=(x))
new_obj.keyframe_insert(data_path='rotation_euler', frame=(x))
c=c+1
scene.frame_set(1)
.blendファイル
スクリプト実行前と後を置いておきます。それぞれのファイルを3Dビューでアニメーションプレビューしてみてください。
動画とAdd-onについて
@CodyWinch さんがAdd-onを公開していて、その動画見たんですけど、カメラに対するオブジェクトのちらつきは(1)Emptyを親にしておいてアニメーション付け、(2)Emptyに移動差分をカウンターとして相殺するアニメーションを付ける、っていう感じで実現しています。
対して上のスクリプトでは、別オブジェクト(Empty)にカメラを親とした時の動きをコマごとにキーを打つ、っていうやり方をしています。
フルコマ、4コマ、8コマ、16コマのサンプルです。
----
8/20版。カメラオブジェクトに親がいる場合を考慮
# (POC) skip frames 2019/08/20
#
# 1. select target object , and camera
# 2. run script
# 3. set constraints to target object (manually)
# copy location -> new_obj
# copy rotation -> new_obj
# 4. play animation
# 5. yaay!!
#
import bpy
import mathutils
m = 4
scene = bpy.context.scene
layer = bpy.context.view_layer
act_obj = bpy.context.object
sel_objs = bpy.context.selected_objects
src_obj = None
if act_obj.type == 'CAMERA':
l = len(sel_objs)
if l == 2:
for x in sel_objs:
if x != act_obj:
src_obj = x
if src_obj != None:
new_obj = bpy.data.objects.new('new_obj', None)
scene.collection.objects.link( new_obj )
tmp_obj = bpy.data.objects.new('tmp_obj', None)
scene.collection.objects.link( tmp_obj )
c = 0
src_obj.select_set(False)
new_obj.select_set(False)
tmp_obj.select_set(True)
for x in range( scene.frame_start, scene.frame_end):
scene.frame_set(x)
layer.update()
if (c % m ) == 0:
if tmp_obj.parent != None:
layer.objects.active = tmp_obj
act_obj.select_set(False )
bpy.ops.object.parent_clear(type='CLEAR')
tmp_obj.location = src_obj.location
tmp_obj.rotation_euler = src_obj.rotation_euler
layer.objects.active = act_obj
act_obj.select_set(True )
bpy.ops.object.parent_set(type='OBJECT', keep_transform=False)
layer.update()
loc , rot, sca = tmp_obj.matrix_world.decompose()
new_obj.location = loc
new_obj.rotation_euler = rot.to_euler()
new_obj.keyframe_insert(data_path='location', frame=(x))
new_obj.keyframe_insert(data_path='rotation_euler', frame=(x))
c=c+1
scene.frame_set(1)
お読みいただきありがとうございます。サポートいただいた分はおやつのグレードアップに使おうかと思います。スキ、SNSにシェアもよろしくお願いします!