Rosso Laboratory

Rosso Laboratory

主に鉄道模型シミュレーター(VRM)などの仮想鉄道アプリを扱うブログです。またHDR写真の記事も書いています。

前方回転カメラ

先月の定例会で話が持ち上がった「編成の前方で回転動作をするカメラ」のスクリプトです。foxさんのような動画を作るにはあった方が良いだろうということでAKAGIさんの撮る夫くんに実装出来ないかな?という話をしていたのですが、こちらは単独動作版です。

少し解説しますと、CreateUserCameraModeで作るユーザーカメラを上書きしていけるか?が焦点だったのですが、結果としては上書きは出来ずに12の新規ユーザーカメラが作られた時点で動作が止まります。なのでDeleteUserCameraModeも使い、消しては作り消しては作りしながら動作させています。回転スクリプト自体は拙作「まるくまわるくん」があったので流用でき短時間で作れました。
操作は [B]で時計周り、[N]で停止、[M]で反時計周りとなります。

#OBJID=xx
import vrmapi
import math
def vrmevent_xx(obj,ev,param):
    di = obj.GetDict()
    if ev == 'init':
        di['circle_r'] = 80
        di['theta'] = 0
        di['thetastep'] = 0.5
        di['ax'] = 0
        di['ay'] = -5
        di['az'] = 0
        di['fx'] = di['ax'] + di['circle_r'] * math.cos(math.radians(di['theta']))
        di['fy'] = 0
        di['fz'] = di['az'] + di['circle_r'] * math.sin(math.radians(di['theta']))
        di['left_evid'] = 0
        di['right_evid'] = 0
        di['eventUID_L'] = 2100004
        di['eventUID_R'] = 2100005
        di['camid'] = obj.CreateUserCameraMode(0,"前面撮影カメラ","frontshoot0",1,0,1,False,True,-di['fx'],di['fy'],di['fz'],di['ax'],di['ay'] ,di['az'],45)
        obj.SetCameraMode(di['camid'])
# [B]で時計周り、[N]で停止、[M]で反時計周り
        obj.SetEventKeyDown('B',300)
        obj.SetEventKeyDown('N',200)
        obj.SetEventKeyDown('M',100)
(中略)
    elif ev == 'timer':
        if param['eventUID'] == di['eventUID_L']:
            di['fx'] = di['ax'] + di['circle_r'] * math.cos(math.radians(di['theta']))
            di['fz'] = di['az'] + di['circle_r'] * math.sin(math.radians(di['theta']))
            obj.DeleteUserCameraMode(di['camid'])
            di['camid'] = obj.CreateUserCameraMode(0,"前面撮影カメラ","frontshoot0",1,0,1,False,True,-di['fx'],di['fy'],di['fz'],di['ax'],di['ay'] ,di['az'],45)
            obj.SetCameraMode(di['camid'])
            di['theta'] = di['theta'] + di['thetastep']
        if param['eventUID'] == di['eventUID_R']:
            di['fx'] = di['ax'] + di['circle_r'] * math.cos(math.radians(di['theta']))
            di['fz'] = di['az'] + di['circle_r'] * math.sin(math.radians(di['theta']))
            obj.DeleteUserCameraMode(di['camid'])
            di['camid'] = obj.CreateUserCameraMode(0,"前面撮影カメラ","frontshoot0",1,0,1,False,True,-di['fx'],di['fy'],di['fz'],di['ax'],di['ay'] ,di['az'],45)
            obj.SetCameraMode(di['camid'])
            di['theta'] = di['theta'] - di['thetastep']
(中略)
    elif ev == 'keydown':
        if param['eventUID'] == 100:
            obj.ResetEvent(di['right_evid'])
            di['left_evid'] = obj.SetEventTimer(0.01,di['eventUID_L'])
        if param['eventUID'] == 200:
            obj.ResetEvent(di['left_evid'])
            obj.ResetEvent(di['right_evid'])
        if param['eventUID'] == 300:
            obj.ResetEvent(di['left_evid'])
            di['right_evid'] = obj.SetEventTimer(0.01,di['eventUID_R'])

さてこれでfoxさんのような動画が撮れるでしょうか。まだまだ大変そうな気はしますね。