LoginSignup
1

More than 1 year has passed since last update.

posted at

updated at

Blenderのカメラのスクリプトの試作2種

ADVENTARのBlender Advent Calendar 2020の23日の記事として登録します
https://adventar.org/calendars/5212

チャットで漫画の下絵に使うためのカメラ操作をする機能が欲しいって話題があったので
ちょっと機能を試作してみました。 どちらも試作で機能としてはメモ書きに近い程度です

目的の位置が中心になるようにカメラをシフトする

カメラシフト(カメラビューのままで平行移動したように表示を変更する機能)の数値を
より簡単にするためにするためのスクリプトです

カメラビューで見た3Dカーソル位置が中心になるようにシフトの数値を設定します
image.png

CameraShift/py
import bpy
import math
from mathutils import Vector, Matrix

scene = bpy.context.scene
camera = scene.camera
camera_data = camera.data

matrix = camera.matrix_world
camera_angle = camera_data.angle
print(camera_angle)


target_location = scene.cursor.location - camera.location
loc = target_location@camera.matrix_world

print(loc)

x_tan = loc[0]/loc[2]
y_tan = loc[1]/loc[2]
angle_tan = math.tan(camera_angle/2)
print(angle_tan)
camera_data.shift_x = -x_tan /(2*angle_tan)
camera_data.shift_y = -y_tan /(2*angle_tan)

逆にカメラでの中心を3Dカーソル位置に移動させる場合には
シフトが0の状態で 最後の2行を

camera_data.shift_x = x_tan /(2*angle_tan)
camera_data.shift_y = y_tan /(2*angle_tan)

と符合を逆転したものを実行するだけです
既にシフトが設定されている状態からは もう少し調整が必要になりますね。

画像の一部分に合わせる形でカメラを設定

漫画の1コマに合わせる形でのレンダリング画像を作りたいといった時に使うスクリプトです

カメラの下絵と画像エディッタに表示する画像を同じにしておいて
画像エディッタ上のアノテーションでカメラに収めたい範囲に印をつけることで
表示範囲とレンダリングの解像度を指定します。
image.png

GpenCrip.py
import bpy
scene = bpy.context.scene
#strokes = bpy.context.annotation_data.layers.active.active_frame.strokes
strokes = bpy.data.grease_pencils[0].layers[0].active_frame.strokes
# アノテーションは3Dビューに使われるものと3Dビューに使われるのがあるのでフィルタリング
strokes_2d = [ s for s in strokes if s.display_mode == '2DSPACE']
x_list = []
y_list = []
for stroke in strokes_2d:
    x_list += [pos.co[0] for pos in stroke.points]
    y_list += [pos.co[1] for pos in stroke.points]

bbox = [min(x_list),min(y_list), max(x_list), max(y_list)]
#カメラの下絵画像の情報を取得
camera = scene.camera
bg_image = camera.data.background_images[0]
bg_size = bg_image.image.size

# 下絵の表示される範囲の設定
bg_image.frame_method = 'CROP'
crop_size = [(bbox[2] -bbox[0])*bg_size[0], (bbox[3] -bbox[1])*bg_size[1]]
# 背景のトリムは背景画像の比率と比べて大きい方を基準にフレームに収めて切り抜く
if bg_size[0] * crop_size[0] > bg_size[1] * crop_size[1]:
    bg_scale = bg_size[0] / crop_size[0]
else:
    bg_scale = bg_size[1] / crop_size[1]
bg_image.scale = bg_scale
# 下絵の中心位置を設定
bg_image.offset = ((bbox[0] + bbox[2] -1) *-0.5 *bg_scale, (bbox[1]+ bbox[3] -1) *-0.5 *bg_scale) 
# レンダリングの画像サイズの設定
scene.render.resolution_x = crop_size[0]
scene.render.resolution_y = crop_size[1]

まだ試作なので アノテーションは最初の1しか取得できないし
下絵と画像エディッタで表示する画像をそろえておく手間はありますが
何かしらの手助けになれば幸いです

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1