Vizardの基本
WorldViz社が提供するPythonベースの仮想環境構築用ソフトウェア
はじめ方
2.SSDを指定しインストール
- 研究室で支給するPCにはHDDとSSDが搭載されています
- ざっくり、SSDはプログラム実行用、HDDはデータ保管用です
- 仮想環境関連のソフトウェアは、SSDにインストールしましょう
- 逆に、個人のOneDriveなどはHDD側に紐づけたほうが効率的です
4.最低限のコードで動かしてみる
- 下記のコードを入力し「F5」キーを押す
piazza = viz.addChild('piazza.osgb')####
- 「W」・「A」・「S」・「D」キーで視点を操作してみる
Wで前進、Sで後退、Aは左でDは右な!
→ 公式チュートリアル
学習の進め方
5.チュートリアルを使って学習
- チュートリアルを開く
- ツールバーから、Help > Getting Started
- 開いた画面で、View tutorial > Tutorials and Examples > Full Tutorials listとたどる
- Getting your feet wetから順番に最後まで、ひととおり学習する
※ たくさんあるように見えますが、3日あればすべて目を通せるはずです。※ Vizard関連の質問には、このチュートリアルを完了している前提で回答します。
- Demoの使い方
- ツールバーから、Help > Getting Started
- Demosのタブをクリックするとデモの一覧が表示される
- 「Run」で各デモの挙動を確認する
- 「Open」で各デモのソースコードを確認する
- Exampleの使い方
- ツールバーから、Help > Getting Started
- Exampleのタブをクリックすると一覧が表示される
- 「Open」で各デモのソースコードを確認する
- 変更して挙動を確認したい場合は、ローカルに保存する
6.ヘルプとフォーラムで検索
- ヘルプを開く
- ツールバーから、Help > Vizard Help
- 左の検索窓に「lighting」などのワードを入力
- 検索結果を問題を解決しそうなトピックを探す
- トピックが難しければ、「Back」で最初から解説を読む
- フォーラムの使い方
- ツールバーから、Help > Support Forum
- Searchタブを選択し、Human Verificationをチェック
- KeyWordを入力し問題を解決しそうなトピックを探す
- 研究室では有料アカウントでの質問も可能です
7.教養としてのPython
- Vizardは、Pythonの知識がなくても何となく使えてしまいます。
- でもVizardが吐き出すエラーコードをちゃんと読み解くにはPythonの知識は必要です。
- 使う人から作る人になるためには、Pythonの言語構造の学習が近道です。
コードを書きはじめる前に
8.権利関連のクレジットの挿入
#####################################################################''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' VIZARD/PYTHON SCRIPT FOR IMMERSIVE 3D EXPERIMENTS. ALL RIGHTS RESERVED YOSHIOKA LAB, CHIBA UNIVERSITY, JAPAN.
This Script Based on using the following equipment. - WorldViz Vizard 7.0 over - VIVE PRO EYE - Cyberith Virtualizer Elite2'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''#####################################################################
9.各種ショートカット
Tab : 一括インデントTab + Shift : 一括インデント削除 F1 : Vizard HelpF5 : 実行F11: ファイルの場所を開くF12: Vizard Directoryを開く
Ctrl + C : コピーCtrl + X : 切り取りCtrl + V : 貼り付けCtrl + Z : 元に戻すCtrl + Y : やり直す Ctrl + F : 検索Ctrl + H : 置換Ctrl + S : 保存Ctrl + W : タブを閉じる
→ 公式チュートリアル
基本のコード その1
HMDの接続関連
import vizimport steamvr
viz.go()piazza = viz.addChild('piazza.osgb')
########### SteamVR HMDの設定 #############import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
Oculus Rift & Oculus Questとの接続
- 仮想環境の提示
- コントローラの接続と操作反映(https://forum.worldviz.com/showthread.php?t=5984)
# Launch graphics windowviz.setMultiSample(8)viz.go()
# Connect to Vive HMDhmd = steamvr.HMD()if not hmd.getSensor(): sys.exit('Vive not detected')
# Connect to Tobii eye trackertobii = viz.add('tobii.dle')eyeTracker = tobii.addEyeTracker()if not eyeTracker: sys.exit('Eye tracker not detected')
# Add indicators to place at gaze intersection pointpoint = vizshape.addSphere(radius=0.05, color=viz.GREEN)point.disable(viz.INTERSECTION)point.visible(False)
# Setup keyboard callbacks to display gaze point and calibratevizact.onkeydown('c', eyeTracker.calibrate)vizact.onkeydown('q', eyeTracker.cancelCalibration)vizact.onkeydown('g', point.visible, viz.TOGGLE)
##########import vizviz.go()
########### SteamVR HMDの設定 #############import steamvrhmd = steamvr.HMD()navigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
####### 全周囲両眼立体視動画の再生設定 ####### def Video_Play(): ############# 再生する動画の読込と両眼天球への貼り付け ############ video_R_Eye = viz.addVideo('spherical_video_Right.mp4') #右目用動画の読込 video_L_Eye = viz.addVideo('spherical_video_Left.mp4') #左目用動画の読込
#Sphere displayed only for Right Eye sphere_R = vizshape.addSphere(flipFaces=True) sphere_R.texture(video_R_Eye) sphere_R.disable(viz.DEPTH_TEST) sphere_R.drawOrder(-100) sphere_R.disable(viz.RENDER_LEFT) viz.link(viz.MainView,sphere_R,mask=viz.LINK_POS)
#Sphere displayed only for Left Eyeimport vizshape sphere_L = vizshape.addSphere(flipFaces=True) sphere_L.texture(video_L_Eye) sphere_L.disable(viz.DEPTH_TEST) sphere_L.drawOrder(-100) sphere_L.disable(viz.RENDER_RIGHT)
viz.link(viz.MainView,sphere_L,mask=viz.LINK_POS) ################ 動画再生速度の変更モジュール ############### ### (UP&DOWN or MouseRight&Left or MouseWheelUp&Down) ### def Speed_Increace(): WALK_SPEED[0] = WALK_SPEED[0] + 1/10. if WALK_SPEED[0] >= 4.3: WALK_SPEED[0] = 4.3 video_R_Eye.setRate(WALK_SPEED[0]) video_L_Eye.setRate(WALK_SPEED[0]) #KEY or Click or Wheel vizact.onkeydown(viz.KEY_UP,Speed_Increace) vizact.onmousedown(viz.MOUSEBUTTON_RIGHT,Speed_Increace) vizact.onwheelup(Speed_Increace) def Speed_Decrease(): WALK_SPEED[0] = WALK_SPEED[0] - 1/10. if WALK_SPEED[0] <= 0.1: WALK_SPEED[0] = 0.1 video_R_Eye.setRate(WALK_SPEED[0]) video_L_Eye.setRate(WALK_SPEED[0]) #KEY or Click or Wheel vizact.onkeydown(viz.KEY_DOWN,Speed_Decrease) vizact.onmousedown(viz.MOUSEBUTTON_LEFT,Speed_Decrease) vizact.onwheeldown(Speed_Decrease) ####################################################### ################ 動画再生 ################ import viztask yield viztask.waitKeyDown( ' ' ) #再生開始 print('Spacebar pressed') video_R_Eye.play() video_L_Eye.play() video_R_Eye.loop() video_L_Eye.loop() import vizcam vizcam.PanoramaNavigate()
viztask.schedule( Video_Play())
# Launch graphics windowviz.setMultiSample(8)viz.go()# Create groundground =viz.addChild('ground.osgb')
# Connect to Vive HMDhmd = steamvr.HMD()if not hmd.getSensor(): sys.exit('Vive not detected')
# Setup navigation node and link to main viewnavigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
#Setup arrow key navigationMOVE_SPEED = 3.0def UpdateView(): yaw,pitch,roll = viewLink.getEuler() m = viz.Matrix.euler(yaw,0,0) dm = viz.getFrameElapsed() * MOVE_SPEED if viz.key.isDown(viz.KEY_UP): m.preTrans([0,0,dm]) if viz.key.isDown(viz.KEY_DOWN): m.preTrans([0,0,-dm]) if viz.key.isDown(viz.KEY_LEFT): m.preTrans([-dm,0,0]) if viz.key.isDown(viz.KEY_RIGHT): m.preTrans([dm,0,0]) navigationNode.setPosition(m.getPosition(), viz.REL_PARENT)vizact.ontimer(0,UpdateView)
HMD上 の視点を操作する_moveToメソッド
hmd = steamvr.HMD()navigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
viz.go()
ground = viz.addChild('ground.osgb')ground.setPosition(0,0.01,0)
############ 視点移動 ############POINT01 = (-4,0,15)POINT02 = (-20,0,15)
action1 = vizact.moveTo(POINT01,speed=1.5)action2 = vizact.moveTo(POINT02,speed=1.5)actions = vizact.sequence(action1,action2 ) def Move():#スペースキーでactionsを実行 navigationNode.addAction(actions)vizact.onkeydown(' ',Move) def Stop():#sでactionsを中断 navigationNode.clearActions()vizact.onkeydown('s',Stop)
def Trans():#'t'で指定した座標に転送 navigationNode.setPosition(25,0,25) vizact.onkeydown('t',Trans)
HMD上 の視点を操作する_moveメソッド
import viz # Vizardメインモジュールのインポートimport vizact # アクションを扱うモジュールのインポートimport steamvr # SteamVR HMDを操作するモジュール
hmd = steamvr.HMD() # HMDのセンサー情報を取得するため、インスタンスを作成PointNode = viz.addGroup() # 座標基準点用のグループノードを作成viewLink = viz.link(PointNode, viz.MainView) # 座標基準点の動きをユーザーの視点にリンクさせるviewLink.preMultLinkable(hmd.getSensor()) # HMDの位置と方向情報を事前に掛け合わせる
viz.go() # Vizardのメインループを開始し、仮想環境をレンダリングviz.addChild('ground.osgb') # 地面のオブジェクトをシーンに追加
####### 視点の等速移動_頭部座標を反映 #######MOVE_SPEED = 1.4 # 移動速度を設定MOVE_DURATION = 10 # 移動時間を設定
# オブジェクトを前進させるアクションを作成(Z方向に等速移動)move_forward = vizact.move(0, 0, MOVE_SPEED, MOVE_DURATION)# moveメソッドの引数(x方向の移動速度、y方向の移動速度、Z方向の移動速度、移動する時間)
# アクションを含んだ関数を定義def Move_Forward(): # 関数名を、Move_Forwardと定義する PointNode.addAction(move_forward) # PointNodeに対して前進アクションを追加
# スペースキーが押されたときに事前に定義した関数(Move_Forward)を呼び出すvizact.onkeydown(' ', Move_Forward)
アイトラッキング
import vizimport steamvr
viz.go()piazza = viz.addChild('piazza.osgb')
########### SteamVR HMDの設定 #############import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
########## EyeTrackingデータの出力 ############VivePro = viz.add('VivePro.dle') eyeTracker = VivePro.addEyeTracker()
def GAZEonTimer(num): gazeMat = eyeTracker.getMatrix()gazeMat.postMult(viz.MainView.getMatrix())line = gazeMat.getLineForward(1000)info = viz.intersect(line.begin, line.end)
GAZE_POSITION = info.pointGAZE_EULER = line.getEuler()
data = str(round(GAZE_POSITION[0],3))+','+str(round(GAZE_POSITION[1],3))+','+str(round(GAZE_POSITION[2],3))+','data += str(round(GAZE_EULER[0],3))+','+str(round(GAZE_EULER[1],3))+','+str(round(GAZE_EULER[2],3))+'\n'print(data)
viz.callback(viz.TIMER_EVENT, GAZEonTimer)viz.starttimer(0,0.1,viz.FOREVER)
import vizimport steamvrimport vizshape
viz.go()piazza = viz.addChild('piazza.osgb')
########### SteamVR HMDの設定 #############import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
########## EyeTrackingデータの出力 ############VivePro = viz.add('VivePro.dle') eyeTracker = VivePro.addEyeTracker()
#Add the fixation point modelpoint = vizshape.addSphere(radius=0.3, color=viz.GREEN)point.disable(viz.INTERSECTION)
def EyePosition_World(): gazeMat = eyeTracker.getMatrix() gazeMat.postMult(viz.MainView.getMatrix()) line = gazeMat.getLineForward(1000) info = viz.intersect(line.begin, line.end) point.setPosition(info.point)recordCallback = vizact.onupdate(0,EyePosition_World)
コントローラーの接続関連
################## VIVE ##################import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
######### コントローラー 複数台接続 #########Controller = steamvr.getControllerList()
for controller in steamvr.getControllerList(): # Create model for controller controller = controller controller.model = controller.addModel() controller.model.disable(viz.INTERSECTION) controller.distance = 1 viz.link(controller, controller.model)
def printer1(): print('Controller1_TriggerON')vizact.onsensordown(Controller[0], steamvr.BUTTON_TRIGGER, printer1)
def printer2(): print('Controller2_TriggerON')vizact.onsensordown(Controller[1], steamvr.BUTTON_TRIGGER, printer2)
#######################################def print_on_timer():Pad_x= Controller[0].getTrackpad() [0]Pad_y= Controller[0].getTrackpad() [1]
if Controller[0].getTrackpad() [0]> 0.5: print ('Pused Value:'), Controller[0].getTrackPad()[0]if Controller[0].getTrackpad() [1]> 0.5: print ('Pused Value:'), Controller[0].getTrackPad()[1]if Controller[0].getTrigger() > 0.5: print ('Pused Value:'), Controller[0].getTrigger()
vizact.ontimer(0.01,print_on_timer)
################## VIVE ##################import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
######### コントローラー 複数台接続 #########Controller = steamvr.getControllerList()
for controller in steamvr.getControllerList(): # Create model for controller controller = controller controller.model = controller.addModel() controller.model.disable(viz.INTERSECTION) controller.distance = 1 viz.link(controller, controller.model)
############### トラックパッドで移動 ############### MOVE_SPEED = 0.5 def UpdateView():yaw,pitch,roll = viewLink.getEuler()m = viz.Matrix.euler(yaw,0,0)dm = viz.getFrameElapsed() * MOVE_SPEED
if Controller[0].getTrackpad()[1] > 0.7: #トラックパッド上を触って前進print ('Pused Value:'), Controller[0].getTrackpad()m.preTrans([0,0,dm])navigationNode.setPosition(m.getPosition(), viz.REL_PARENT) if Controller[0].getTrackpad()[1] < -0.2: #トラックパッド下を触って後退print ('Pused Value:'), Controller[0].getTrackpad()m.preTrans([0,0,-dm])navigationNode.setPosition(m.getPosition(), viz.REL_PARENT) vizact.ontimer(0.01,UpdateView) ####################################################
# Launch graphics windowviz.setMultiSample(8)viz.go()# Create groundground =viz.addChild('ground.osgb')
# Connect to Vive HMDhmd = steamvr.HMD()if not hmd.getSensor(): sys.exit('Vive not detected')
# Setup navigation node and link to main viewnavigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
############### move ############### Controller = steamvr.getControllerList() for controller in steamvr.getControllerList(): # Create model for controller controller = controller controller.model = controller.addModel() controller.model.disable(viz.INTERSECTION) controller.distance = 1.0 viz.link(controller, controller.model) MOVE_SPEED = 3.0def UpdateView(): yaw,pitch,roll = viewLink.getEuler() m = viz.Matrix.euler(yaw,0,0) dm = viz.getFrameElapsed() * MOVE_SPEED if Controller[0].getTrigger(): m.preTrans([0,0,dm]) navigationNode.setPosition(m.getPosition(), viz.REL_PARENT)vizact.ontimer(0,UpdateView)
def UpdateView(): yaw,pitch,roll = viewLink.getEuler() m = viz.Matrix.euler(yaw,0,0) dm = viz.getFrameElapsed() * MOVE_SPEED if Controller[1].getTrigger(): m.preTrans([0,0,-dm]) navigationNode.setPosition(m.getPosition(), viz.REL_PARENT)vizact.ontimer(0,UpdateView)
### 実行 ###viz.fov(80) viz.MainView.setPosition([0, 1.5, 0]) viz.go() ground = viz.addChild('ground.osgb')
### リストで初期値を設定(global関数を使わずに済む) ###Height = [0] Height[0] = 1.25 #上下の初期値
Side = [0] Side[0] = 0 #左右の初期値
Distance = [0] Distance[0] = 2.5#奥行の初期値### 壁 ###Wall = vizshape.addBox(size = [5.0,2.5,0.1])Wall.setPosition(Side[0],Height[0],Distance[0])#設定した初期値に壁を配置############################## VIVE HMD ################################import steamvr
# Setup SteamVR HMDhmd = steamvr.HMD()if not hmd.getSensor(): sys.exit('SteamVR HMD not detected')
# Setup navigation node and link to main viewnavigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
######################### VIVE CONTROLLER ##############################VIVE左右コントローラーのリスト作成 Controller = steamvr.getControllerList()#Add controllersfor controller in steamvr.getControllerList():
# Create model for controller controller.model = controller.addModel(parent=navigationNode) if not controller.model: controller.model = viz.addGroup(parent=navigationNode) controller.model.disable(viz.INTERSECTION) viz.link(controller, controller.model)
#### コントローラー0による操作(なめらかな操作などに応用) ###########def print_on_timer(): Pad_x= Controller[0].getTrackpad() [0]#Pad_xはTrackPadの左右方向の反応値(-1から1) Pad_y= Controller[0].getTrackpad() [1]#Pad_yはTrackPadの上下方向の反応値(-1から1)
if Controller[0].getTrackpad() [0]> 0.5:#TrackPadの右を押すと右に移動 Side[0] += 0.01 Wall.setPosition(Side[0],Height[0],Distance[0]) print ('con_0 Pad_x value:' , Controller[0].getTrackpad()[0]) if Controller[0].getTrackpad() [0]< -0.5:#TrackPadの左を押すと左に移動 Side[0] -= 0.01 Wall.setPosition(Side[0],Height[0],Distance[0]) print ('con_0 Pad_x value:' , Controller[0].getTrackpad()[0]) if Controller[0].getTrackpad() [1]> 0.5:#TrackPadの上を押すと上に移動 Height[0] += 0.01 Wall.setPosition(Side[0],Height[0],Distance[0]) print ('con_0 Pad_y value:' , Controller[0].getTrackpad()[1]) if Controller[0].getTrackpad() [1]< -0.5:#TrackPadの下を押すと下に移動 Height[0] -= 0.01 Wall.setPosition(Side[0],Height[0],Distance[0]) print ('con_0 Pad_y value:' , Controller[0].getTrackpad()[1]) if Controller[0].getTrigger() > 0.5:#Triggerを押すと奥に移動 Distance[0] += 0.01 Wall.setPosition(Side[0],Height[0],Distance[0]) print ('con_0 Tri Value:', Controller[0].getTrigger()) vizact.ontimer(0.01,print_on_timer)
##### コントローラー1による操作(ON,OFFの切り替えなどに応用) ##########
#TrackPadに触れると壁を初期位置に戻すdef Reset(): Side[0] = 0 Height[0] = 1.25 Distance[0] = 2.5 Wall.setPosition(Side[0],Height[0],Distance[0]) print ('con_1 Pad ON:')vizact.onsensordown(Controller[1], steamvr.BUTTON_TRACKPAD, Reset)#Triggerを押すたびに壁が手前に動く def pull(): Distance[0] -= 0.1 Wall.setPosition(Side[0],Height[0],Distance[0]) print ('con_1 Tri ON:')vizact.onsensordown(Controller[1], steamvr.BUTTON_TRIGGER, pull)
hmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
###地面の作成###ground = vizshape.addBox(color = viz.WHITE)ground.setScale(50,0.1,50)ground.setPosition(0,-0.05,0)ground.disable(viz.LIGHTING)
#鉄パイプの作成Pipe1 = vizshape.addCylinder(height = 1.8,radius = 0.015,topRadius = None,bottomRadius = None,axis = vizshape.AXIS_Y,slices = 20,bottom = False,top = False)Pipe1.color(0.7,0.7,0.7)Pipe1.disable(viz.LIGHTING)Pipe1.setPosition(0,0.1,0)Pipe1.setEuler(90,90,0)
#鉄パイプ中央に目印作成Ring = vizshape.addCylinder(height = 0.05,radius = 0.016,topRadius = None,bottomRadius = None,axis = vizshape.AXIS_Y,slices = 20,bottom = False,top = False,color = viz.BLUE)Ring.setParent(Pipe1)
############### コントローラーの設定(VR用) ##########
Controller = steamvr.getControllerList()
for controller in steamvr.getControllerList(): controller = controller controller.model = controller.addModel() controller.model.disable(viz.INTERSECTION) controller.distance = 1 link = viz.link(controller, Pipe1) #コントローラーの位置とパイプの位置をリンクさせる link.preEuler([0, 105, 0]) #コントローラーとパイプの角度の関係を設定(コントローラ-を地面に置いたときにパイプが平らに置けるように)
viz.go()viz.setMultiSample(4)viz.fov(80)
# Setup SteamVR HMDhmd = steamvr.HMD()if not hmd.getSensor(): sys.exit('SteamVR HMD not detected')
# Setup navigation node and link to main viewnavigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
############### コントローラのセット ###########################Controller = steamvr.getControllerList()
for controller in steamvr.getControllerList(): # Create model for controller controller = controller controller.model = controller.addModel() controller.model.disable(viz.INTERSECTION) controller.distance = 1 viz.link(controller, controller.model)
#################### 地面の生成 ################ground =vizshape.addBox(size=[16,0.1,200],pos=[0,0,0])
############# 動くボールをつくる ##################ball = vizshape.addSphere(radius=0.05,color=viz.GREEN)ball.setPosition(0,0.1,0)def updateDirect():
X = viz.MainView.getPosition()[0] Z = viz.MainView.getPosition()[1] Y = viz.MainView.getPosition()[2] height = Controller[0].getPosition()[1] Yaw = Controller[0].getEuler()[0] Pitch = Controller[0].getEuler()[1] Roll = Controller[0].getEuler()[2]
B1 = ball.getPosition()[0] B2 = ball.getPosition()[1] B3 = ball.getPosition()[2] tp = Controller[0].getTrackpad()[1] tpp = Controller[0].getTrackpad()[0] #コントローラーのトリガーを押しながら地面を指し、ボールを移動させる if Controller[0].getTrigger() > 0.5: ball.setPosition([(height / math.tan((Pitch)*math.pi/180)) * math.sin(Yaw*math.pi/180)+X, 0.1 , height / math.tan((Pitch)*math.pi/180)* math.cos(Yaw*math.pi/180)+Y]) #操作がないときボールに与えられたすべてのアクション(直進)を一旦停止 elif -0.5< tp <0.5 and -0.5< tpp <0.5 : ball.clearActions() #トラックパッドで細かい調節も可能 else: if tp >0.5: move = vizact.move(0,0,0.5,0.1) if tpp >0.5: move = vizact.move(0.5,0,0,0.1) if tp < -0.5: move = vizact.move(0,0,-0.5,0.1) if tpp < -0.5: move = vizact.move(-0.5,0,0,0.1) ball.add(move) #コントローラーのGRIPを押してボール位置をリセットする def Ball_Reset(): ball.setPosition(0, 0.1, 0) vizact.onsensordown(Controller[0], steamvr.BUTTON_GRIP, Ball_Reset) #ボールの位置座標を出力 print(round(B1,2),round(B2,2),round(B3,2))
vizact.onupdate(0, updateDirect)
トラッカーの接続関連
viz.go()piazza = viz.addChild('piazza.osgb')
########### SteamVR HMDの設定 #############import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
########## トラッカーのデータ出力 ############tracker1 = steamvr.getTrackerList()[0]tracker2 = steamvr.getTrackerList()[1]
def TrackeronTimer(num):Tracker1_pos = tracker1.getPosition()Tracker2_pos = tracker2.getPosition()
data = str(round(Tracker1_pos[0],3))+'\t'+str(round(Tracker1_pos[1],3))+'\t'+str(round(Tracker1_pos[2],3))+'\t'data += str(round(Tracker2_pos[0],3))+'\t'+str(round(Tracker2_pos[1],3))+'\t'+str(round(Tracker2_pos[2],3))+'\n'print(data)
viz.callback(viz.TIMER_EVENT, TrackeronTimer)
Viveトラッカーによる歩行
viz.go()viz.setMultiSample(4)viz.fov(80)
###########VIVE##################import steamvr
# Setup SteamVR HMDhmd = steamvr.HMD()if not hmd.getSensor(): sys.exit('SteamVR HMD not detected')
# Setup navigation node and link to main viewnavigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor()) ##################### 視点の移動制御 ###################### global View_SPD #関数をまたいで使用できるようにボールスピード(View_SPD)をグローバル変数に設定View_SPD = 0.0000001 #View_SPDの初期値を0.1M/Sに設定view = viz.MainView##########VIVE################## R_foot =vizshape.addCylinder(0.10,0.03)L_foot =vizshape.addCylinder(0.10,0.03)
tracker1 = steamvr.getTrackerList()[0]tracker2 = steamvr.getTrackerList()[1]
viz.link(tracker1,R_foot)viz.link(tracker2,L_foot)###################################足踏みで進む##################################################def footstamp(): L_foot_pos = tracker1.getPosition() R_foot_pos = tracker2.getPosition() L_z= L_foot_pos[1] R_z= R_foot_pos[1] print(L_z, R_z) view = viz.MainView #画面表示の主視点をviewと名付ける global View_SPD #関数をまたいで使用できるようにボールスピード(View_SPD)をグローバル変数に設定 V=0.15 if L_z <= V and R_z <= V: global View_SPD view.clearActions() #ボールに与えられたすべてのアクション(直進)を一旦停止 navigationNode.clearActions() View_POS = viz.MainView.getPosition() curr_time = time.clock() #現在の時間をcurr_timeとする print(round(curr_time,2),round(View_POS[2],2),round(View_SPD,2)) #時刻、位置、スピードをインタラクティブに表示 if L_z > V or R_z > V: global View_SPD View_SPD = 1.0 #グローバル変数View_SPDを2.0m/sに変更(加速) View_POS = viz.MainView.getPosition() moveTWD = vizact.moveTo(pos=[0,0,50],speed=1.5) #加速したView_SPDで直進する運動を作成 view.addAction(moveTWD) #主視点に”moveTWD”を適用 navigationNode.addAction(moveTWD) curr_time = time.clock() #現在の時間をcurr_timeとする print(round(curr_time,2),round(View_POS[2],2),round(View_SPD,2)) #時刻、位置、スピードをインタラクティブに表示
vizact.ontimer(0,footstamp) #足の判定を呼び続ける
データの計測と出力
viz.go()piazza = viz.addChild('piazza.osgb')
#### 被験者番号の設定SUBJECT_NUMBER = 1 #被験者番号の入力
#### データ出力先のファイルの指定(なければ作成)FileName='Experiment'+datetime.datetime.today().strftime("%Y%m%d")+'_Sub'+str(SUBJECT_NUMBER)+'.txt'expelimental_data = open(FileName,'a')
#### ヘッダー(第一行)の挿入 Header = 'Sub'+'Lap'+'\t'+'PosX'+'\t'+'PosY'+'\t'+'PosZ'+'\t'+'Yaw'+'\t'+'Pitch'+'\t'+'Roll'+'\n'expelimental_data.write(Header)
#### タイマーの設定(複数のタイマーを同時に走らすこともできる) TIMER_ID = 1 #タイマーはID番号で管理 TIMER_PERIOD = 0.1 #出力間隔[s]
#### データ出力START_TIME =time.time() #プログラムを動かしはじめた時刻を記録
def onTimer(num): PASSED_TIME = time.time()-START_TIME POS = viz.MainView.getPosition() ORI = viz.MainView.getEuler() data = str(SUBJECT_NUMBER)+'\t'+str(round(PASSED_TIME,1))+'\t' data += str(round(POS[0],2))+'\t'+str(round(POS[1],2))+'\t'+str(round(POS[2],2))+'\t' data += str(round(ORI[0],2))+'\t'+str(round(ORI[1],2))+'\t'+str(round(ORI[2],2))+'\n' print(data) expelimental_data.write(data) viz.starttimer(TIMER_ID, TIMER_PERIOD, viz.PERPETUAL)viz.callback(viz.TIMER_EVENT, onTimer)
viz.go()piazza = viz.addChild('piazza.osgb')
#### 被験者番号の設定SUBJECT_NUMBER = 1 #被験者番号の入力
#### データ出力先のファイルの指定(なければ作成)FileName='Experiment'+datetime.datetime.today().strftime("%Y%m%d")+'_Sub'+str(SUBJECT_NUMBER)+'.csv'expelimental_data = open(FileName,'a')
#### ヘッダー(第一行)の挿入 Header = 'Sub'+','+'Lap'+','+'PosX'+','+'PosY'+','+'PosZ'+','+'Yaw'+','+'Pitch'+','+'Roll'+'\n'expelimental_data.write(Header)
#### タイマーの設定(複数のタイマーを同時に走らすこともできる) TIMER_ID = 1 #タイマーはID番号で管理 TIMER_PERIOD = 0.1 #出力間隔[s]
#### データ出力START_TIME =time.time() #プログラムを動かしはじめた時刻を記録
def onTimer(num): PASSED_TIME = time.time()-START_TIME POS = viz.MainView.getPosition() ORI = viz.MainView.getEuler() data = str(SUBJECT_NUMBER)+','+str(round(PASSED_TIME,1))+',' data += str(round(POS[0],2))+','+str(round(POS[1],2))+','+str(round(POS[2],2))+',' data += str(round(ORI[0],2))+','+str(round(ORI[1],2))+','+str(round(ORI[2],2))+'\n' print(data) expelimental_data.write(data) viz.starttimer(TIMER_ID, TIMER_PERIOD, viz.PERPETUAL)viz.callback(viz.TIMER_EVENT, onTimer)
### 基本設定 ###viz.go()viz.fov(80)viz.clearcolor(viz.WHITE)### 時間計測の準備 ###
#start_timeにはプログラム開始時からの時間が記録されるstart_time = viz.tick() #時間リセット用リストの定義reset_time = [0]reset_time[0] = 0#Timerの設定TIMER_ID = 1 #データ保存タイマーIDTIMER_PERIOD = 0.1 #データ保存間隔[s]
### 地面の作成 ###ground = vizshape.addBox(color = viz.WHITE)ground.setScale(50,0.1,50)ground.setPosition(0,-0.05,0)
### Excelデータの作成 ###expelimental_data = open('timer'+'.csv', 'a')
#ヘッダーの入力header = 'time'+'\n'expelimental_data.write(header) #### 0.1秒ごとに行う処理 ####
def onTimer(num): curr_time = viz.tick() - reset_time[0] #現在時間ーリセット時間(初期値0)
data = str(round(curr_time,1))+'\n' #curr_timeを小数第1まで書き込む expelimental_data.write(data) print(data) ### タイマーを開始しデータを記録 ### viz.callback(viz.TIMER_EVENT, onTimer)viz.starttimer(TIMER_ID, TIMER_PERIOD, viz.PERPETUAL)
#スペースキーを押した時間がreset_time[0]となるdef ResetTimer(): reset_time[0] = viz.tick()vizact.onkeydown(' ',ResetTimer)
鑑賞時間 の計測
n = 4 #目標点の個数を設定Area_MAX = 2 #counterが反応する目標点からの最大距離(m)Deg = 30 #counterが反応する角度(目標点正面を向くと0) Points = []Counts = []for x in range(n): Points.append(x) Counts.append(x) Counts[x] = 0 #nで指定した個数だけ目標点の座標を記すPoints[0] = (2,9) #x=2(左右), y=9(奥行)Points[1] = (1,6) Points[2] = (-3,5) Points[3] = (0,3)
############# 周囲環境 ##################viz.go()viz.fov(100)#HMDをつなぐときはコメントアウトground = viz.addChild('ground.osgb')
#目標点の位置に円柱を配置して視覚化Pole_1 = vizshape.addCylinder(height=3,radius=0.1,pos=(Points[0][0],1.5,Points[0][1]),color=viz.RED) #高さ3m,半径0.1mPole_2 = vizshape.addCylinder(height=3,radius=0.1,pos=(Points[1][0],1.5,Points[1][1]),color=viz.BLUE)Pole_3 = vizshape.addCylinder(height=3,radius=0.1,pos=(Points[2][0],1.5,Points[2][1]),color=viz.GREEN)Pole_4 = vizshape.addCylinder(height=3,radius=0.1,pos=(Points[3][0],1.5,Points[3][1]),color=viz.WHITE)
############# 0.1秒ごとに行う処理 ##################def Counter(num): POS_HEAD = viz.MainView.getPosition() ORI_HEAD = viz.MainView.getEuler() X = POS_HEAD[0] Y = POS_HEAD[2] A = ORI_HEAD[0]#被験者が向いている角度(yaw)
for k in range(n): #目標点と自分を結ぶ直線が、Y軸に直行なベクトル(0,1)となす角を求める。 cosP = (Points[k][1]-Y)/math.sqrt(pow(Points[k][0]-X,2)+pow(Points[k][1]-Y,2)) #目標点との位置関係によってPの符号が変わる if Points[k][0]<X: P = -math.degrees(math.acos(cosP)) else: P = math.degrees(math.acos(cosP)) #被験者がエリア内にいるとき if math.sqrt(pow(Points[k][0]-X,2)+pow(Points[k][1]-Y,2))<Area_MAX: #被験者が見ている方向が目標点の方向±Deg°になったらカウントする if -(180-Deg/2)<=A<=(180-Deg/2) and A-Deg<=P<=A+Deg: Counts[k]+=0.1 if A<-(180-Deg/2) or (180-Deg/2)<A: if A-Deg<=P<=A+Deg or abs(A)-Deg<=P<=abs(A)+Deg: Counts[k]+=0.1 data = 'count1'+'\t'+str(round(Counts[0],2))+'\t'+'count2'+'\t'+str(round(Counts[1],2))+'\t'+'count3'+'\t'+str(round(Counts[2],2))+'\t'+'count4'+'\t'+str(round(Counts[3],2))+'\n' print(data) viz.callback(viz.TIMER_EVENT, Counter)viz.starttimer(1, 0.1, viz.PERPETUAL)############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
基本的なオブジェクトの配置と調整
白い部屋 (addBoxの基本)
### 実行 ###viz.fov(80) #PC画面上での視野角が80度になる(VR使用時はコメントアウト)viz.MainView.setPosition([0, 1.5, 0]) #PC画面上での初期視点高さを1.5mに設定viz.go() #出力結果を画面に表示するために必須
### 前の壁 ###Wall_front= vizshape.addBox(size = [5.0,2.5,0.1])#横幅5m,高さ2.5m,厚さ0.1mWall_front.setPosition(0,1.25,2.5)#壁の中心の座標を指定(高さ1.25m,前方2.5m)
### 後の壁 ###Wall_back= vizshape.addBox(size = [5.0,2.5,0.1])#横幅5m,高さ2.5m,厚さ0.1mWall_back.setPosition(0,1.25,-2.5)#壁の中心の座標を指定(高さ1.25m,後方2.5m)
### 右の壁 ###Wall_right= vizshape.addBox(size = [0.1,2.5,5.0])#厚さ0.1m,高さ2.5m,奥行5mWall_right.setPosition(2.5,1.25,0)#壁の中心の座標を指定(高さ1.25m,右側2.5m)
## 左の壁 ###Wall_left= vizshape.addBox(size = [0.1,2.5,5.0])#厚さ0.1m,高さ2.5m,奥行5mWall_left.setPosition(-2.5,1.25,0)#壁の中心の座標を指定(高さ1.25m,左側2.5m)
## 天井 ###Ceiling = vizshape.addBox(size = [5,0.1,5.0])#厚さ0.1m,5m×5mCeiling.setPosition(0,2.55,0)#天井の中心の座標を指定(高さ2.55m※厚さを考慮)Ceiling.disable(viz.LIGHTING)#ライティングをオフ(どの角度でみても色が変わらない)
## 床 ###slab1 = viz.addTexQuad(size = [5,5])#5m×5m(addTexQuadは厚さがない)slab1.setEuler([0,90,0])#地面に水平にさせるために回転させるslab1.disable(viz.LIGHTING)#ライティングをオフ(どの角度でみても色が変わらない)
円柱 (addCylinderの基本)
# Launch graphics windowviz.setMultiSample(8)viz.go()
#hmd = steamvr.HMD()## Setup navigation node and link to main view#navigationNode = viz.addGroup()#viewLink = viz.link(navigationNode, viz.MainView)#viewLink.preMultLinkable(hmd.getSensor())
render1 = vizshape.addCylinder(height=10,radius=0.25)render1.color(r=0.83,g=0.6, b=0.85) render1.setPosition((0,0.0, 20))
render2 = vizshape.addCylinder(height=10,radius=0.25)render2.color(r=0.83,g=0.6, b=0.85)render2.setPosition((-3,0.0, 10))
render3 = vizshape.addCylinder(height=10,radius=0.25)render3.color(r=0.83,g=0.6, b=0.85)render3.setPosition((3,0.0, 10))
for文による繰り返し(box大量配置)
########## ボックス #############Wide = 4 #道幅x = 2 #左右に設置する個数y = 2 #前後に設置する個数
x_start = -(20+Wide)*x+10+Wide/2y_start = -(20+Wide)*y+10
for X in range (2*x):for Y in range (2*y): Box_FrontRight = vizshape.addBox(size=[20,3,20],color=[0.8,0.8,0.8]) # Box_FrontRight.disable(viz.LIGHTING) Box_FrontRight.setPosition(x_start+(20+Wide)*X,1.5,y_start+(20+Wide)*Y)
天井を上下させる
### 実行 ###
viz.fov(80)viz.MainView.setPosition([0, 1.5, 0]) ground = viz.addChild('ground.osgb')viz.go()
CEILING_HEIGHT =[0] #グローバル設定(時系列出力データに載せるために必要)
### 調整空間 ###def AdjustingSpace(CL_HEIGHT): #前にセットしたオブジェクトをすべて取り除く children = viz.MainScene.getChildren() for child in children: child.remove() ### 前の壁 ### Wall_front= vizshape.addBox(size = [5.0,10.0,0.1]) Wall_front.setPosition(0,0,2.5) ### 後の壁 ### Wall_back= vizshape.addBox(size = [5.0,10.0,0.1]) Wall_back.setPosition(0,0,-2.5) ### 右の壁 ### Wall_right= vizshape.addBox(size = [0.1,10.0,5.0]) Wall_right.setPosition(2.5,0,0) ## 左の壁 ### Wall_left= vizshape.addBox(size = [0.1,10.0,5.0]) Wall_left.setPosition(-2.5,0,0) ## 床 ### slab1 = viz.addTexQuad(size = [5,5]) slab1.setEuler([0,90,0]) slab1.disable(viz.LIGHTING) UpLight = viz.addLight() ; UpLight.setEuler(0,-90,0) ; UpLight.intensity(0.6) DownLight = viz.addLight() ; DownLight.setEuler(0,90,0) ; DownLight.intensity(1)
### 動く天井 ### CEILING_HEIGHT[0] =CL_HEIGHT Ceiling = vizshape.addBox(size = [5.0,0.1,5.0]) Ceiling.setPosition(0,CEILING_HEIGHT[0],0) Ceiling.disable(viz.LIGHTING) ### 天井をあげる関数 ### def Increace(): CEILING_HEIGHT[0] = CEILING_HEIGHT[0] + 5.0/100. Ceiling.setPosition(0, CEILING_HEIGHT[0], 0) print('Increace', CEILING_HEIGHT[0]) vizact.onkeydown(viz.KEY_UP,Increace)#↑キーで天井が上昇 ### 天井をさげる関数 ### def Decreace(): CEILING_HEIGHT[0] = CEILING_HEIGHT[0] - 1.0/100. Ceiling.setPosition(0, CEILING_HEIGHT[0], 0) print('Decreace', CEILING_HEIGHT[0])
vizact.onkeydown(viz.KEY_DOWN,Decreace)#↓キーで天井が下降########### コントローラーと接続すると以下のコードも使用可能 ######### def Increace2():# if Controller[0].getTrigger() > 0.5:# CEILING_HEIGHT[0] = CEILING_HEIGHT[0] + 1.0/100.# Ceiling.setPosition(0, CEILING_HEIGHT[0], 0)# print('Increace', CEILING_HEIGHT[0])# # vizact.ontimer(0.1,Increace2)# # def Decrease2():# if Controller[1].getTrigger() > 0.5:# CEILING_HEIGHT[0] = CEILING_HEIGHT[0] - 1.0/100.# Ceiling.setPosition(0, CEILING_HEIGHT[0], 0)# print('Decrease', CEILING_HEIGHT[0])## vizact.ontimer(0.1,Decrease2)
vizact.onkeydown('a',AdjustingSpace,2.1) #aキーを押すと初期高さ2.1mからの調整vizact.onkeydown('b',AdjustingSpace,2.6) #bキーを押すと初期高さ2.6mからの調整
### プログラムの終了 ###vizact.onkeydown('k',viz.quit)
サイズを調節する
viz.go()viz.setMultiSample(4)viz.fov(80)
#################### 地面の生成 ################ground =viz.addChild('ground.osgb')
############# サイズを変更するバーをつくる #############
bar = vizshape.addBox(size = [1,0.1,0.1],color=viz.YELLOW)bar.setPosition(0,0.5,2)bar.disable(viz.LIGHTING)
x,y = [0],[0]x[0],y[0] = 1,1
def change(): bar.setScale(x[0],1,y[0]) #barのサイズ=元のサイズ[1,0.1,0.1]×Scale[x[0],1,y[0]] print('size:',round(x[0]*1,2),0.1,round(y[0]*0.1,2))
#奥行(Y方向)は元のサイズが横幅(X方向)の1/10なので感度を10倍に設定しているdef biggerY(): y[0]+=1 change()def smallerY(): y[0]-=1 y[0] = max(0,y[0]) change()def biggerX(): x[0]+=0.1 change()def smallerX(): x[0]-=0.1 x[0] = max(0,x[0]) change() vizact.onkeydown(viz.KEY_UP,biggerY)#上キーで奥行長く vizact.onkeydown(viz.KEY_DOWN,smallerY)#下キーで奥行短く vizact.onkeydown(viz.KEY_RIGHT,biggerX)#右キーで横幅長く vizact.onkeydown(viz.KEY_LEFT,smallerX)#左キーで横幅短く
基本のコード その2
彩色とテクスチャー
オブジェクトの彩色
### 実行 ###viz.fov(80) viz.MainView.setPosition([0, 1.5, 0]) viz.go()
### 前の壁 ####一般色であれば、色名指定で変更できるWall_front= vizshape.addBox(size = [5.0,2.5,0.1],color = viz.RED)Wall_front.setPosition(0,1.25,2.5)
### 後の壁 ####rgb値(それぞれ最大1)で指定することもできるWall_back= vizshape.addBox(size = [5.0,2.5,0.1],color = [0,1,0])Wall_back.setPosition(0,1.25,-2.5)
### 右の壁 ####colorは後から変更可能(実験途中で変更する場合などに有効)Wall_right= vizshape.addBox(size = [0.1,2.5,5.0])Wall_right.setPosition(2.5,1.25,0)Wall_right.color(viz.BLUE)
## 左の壁 ####.disable(viz.LIGHTING)を使用すると影ができなくなるWall_left= vizshape.addBox(size = [0.1,2.5,5.0])Wall_left.setPosition(-2.5,1.25,0)Wall_left.color([1,1,0.2])Wall_left.disable(viz.LIGHTING)#ライティングをオフ(どの角度でみても色が変わらない)
#背景色の変更viz.clearcolor([1,1,1])
テクスチャのはり方
### 実行 ###viz.fov(80) viz.MainView.setPosition([0, 1.5, 0]) viz.go() #画像をインポートbrick = viz.addTexture('brick.jpg')#タイル画像用に再度インポートbricks = viz.addTexture('brick.jpg')bricks.wrap(viz.WRAP_T, viz.REPEAT)bricks.wrap(viz.WRAP_S, viz.REPEAT)
### 前の壁 ####画像べた張り。サイズが合っていないと画像が歪むWall_front= vizshape.addBox(size = [5.0,2.5,0.1])Wall_front.setPosition(0,1.25,2.5)Wall_front.texture(brick)Wall_front.disable(viz.LIGHTING)#ライティングをオフ(どの角度でみても色が変わらない)
### 後の壁 ####タイル風。壁を横5分割、高さ2.5分割、奥行き0.1mに分割しておく。1区分に1枚の画像matrix = vizmat.Transform()matrix.setScale(5.0,2.5,0.1)
Wall_back= vizshape.addBox(size = [5.0,2.5,0.1])Wall_back.setPosition(0,1.25,-2.5)Wall_back.texmat(matrix)Wall_back.texture(bricks)Wall_back.disable(viz.LIGHTING)#ライティングをオフ(どの角度でみても色が変わらない)
### 右の壁 ####タイル風。壁を横10分割、高さ2.5分割、奥行き0.1mに分割しておく。1区分に1枚の画像matrix2 = vizmat.Transform()matrix2.setScale(10,2.5,0.1)
Wall_right= vizshape.addBox(size = [0.1,2.5,5.0])Wall_right.setPosition(2.5,1.25,0)Wall_right.texmat(matrix2)Wall_right.texture(bricks)Wall_right.disable(viz.LIGHTING)#ライティングをオフ(どの角度でみても色が変わらない)
## 左の箱 ####各面に違う画像をはるときはsplitFaces=Trueにしてnodeを指定するWall_left= vizshape.addBox(size = [2.0,2.5,2.0],splitFaces=True)Wall_left.setPosition(-4,1.25,0)Wall_left.texmat(matrix,node='right')Wall_left.texture(bricks,node='right')Wall_left.disable(viz.LIGHTING)#ライティングをオフ(どの角度でみても色が変わらない)
壁面をカラフルに配色する
viz.setMultiSample(4)viz.MainView.setPosition(-20,1.5,0)viz.MainView.setEuler(270,0,0)viz.MainScene.fog(0.005)#奥をかすませるviz.go()
ground = vizshape.addBox(size = [200,0.01,200], color = [1,1,1])ground.disable(viz.LIGHTING)ground.setPosition([0,0,0])
##### 壁の設定 ######x_range = 100 #壁の横の長さy_range = 9 #壁の縦の長さ
road_width = 6 #道の幅員wall_size = [0.3,0.3]#グリッド幅rate_color= 80 #色を塗る割合[%]
colors = [[0,0,1],[0,1,0],[0,1,1]] #RGB 色を追加してもOK(5色とか)
#############z = road_width/2z2 = -zcenter = -(x_range/2)colorwall = int(x_range*y_range*rate_color/100)#塗る枚数
### 壁をつくる関数 ###def make_wall(z): walls = [] for x in range(x_range): for y in range(y_range): wall = viz.addTexQuad(size = wall_size) wall.setPosition([center+x*wall_size[0],y*wall_size[1]+wall_size[1],z]) wall.disable(viz.LIGHTING) walls.append(wall)
random.shuffle(walls) for s in range(len(colors)): for v in range(int(colorwall/len(colors))): walls[s*int(colorwall/len(colors))+v].color(colors[s]) return walls wall1 = make_wall(z)wall2 = make_wall(z2)
for x in range(x_range*y_range): wall2[x].setEuler([180,0,0])
関数の実行方法
キーボード操作による関数の実行
### 実行 ###viz.fov(80) viz.MainView.setPosition([0, 1.5, 0]) viz.go() ground = viz.addChild('ground.osgb')### 壁 ###Wall = vizshape.addBox(size = [5.0,2.5,0.1])Wall.setPosition(0,1.25,2.5)
Height = 1.25 #壁の高さの初期値Distance = 2.5 #壁までの距離の初期値#fキーを押したとき壁までの距離を遠くするdef Far(): global Distance #Distanceが他の関数内でも参照できるように Distance = 5.0 Wall.setPosition(0,Height,Distance)vizact.onkeydown('f',Far)#入力キーによって処理が変わる。r,bキーで色を変更、1,2,3キーでサイズ変更def Choice(key): if str(key) == 'red': Wall.color(viz.RED) elif str(key) == 'blue': Wall.color(viz.BLUE) else: Wall.setScale(int(key),int(key),int(key))vizact.onkeydown('r',Choice,'red')vizact.onkeydown('b',Choice,'blue')vizact.onkeydown('1',Choice,1)vizact.onkeydown('2',Choice,2)vizact.onkeydown('3',Choice,3)#上キー、マウスホイール上回転で壁の位置を高くするdef Up(): global Height#Heightが他の関数内でも参照できるように Height += 0.1 Wall.setPosition(0,Height,Distance)vizact.onkeydown(viz.KEY_UP,Up)vizact.onwheelup(Up)#下キー、マウスホイール下回転で壁の位置を低くするdef Down(): global Height#Heightが他の関数内でも参照できるように Height -= 0.1 Wall.setPosition(0,Height,Distance)vizact.onkeydown(viz.KEY_DOWN,Down) vizact.onwheeldown(Down)#スペースキーで変更をリセットdef Normal(): global Height #Heightが他の関数内でも参照できるように global Distance #Distanceが他の関数内でも参照できるように Height = 1.25 Distance = 2.5 Wall.setPosition(0,Height,Distance) Wall.setScale(1,1,1) Wall.color(viz.WHITE)vizact.onkeydown(' ',Normal)#0キーを押してから3秒後に終了するdef Finish(): def Fin(): viz.quit() vizact.ontimer2(3,0,Fin)vizact.onkeydown('0',Finish)
キーの打鍵回数により処理変更
def number():#'n'の値に応じた処理を行わせる
print(n[0]) if n[0] == 0: wood[2].setEuler(10,0,0) wood[0].setPosition(-1.7,0.05,3) wood[1].setPosition(-1.7,0.05,3.2) wood[2].setPosition(-1.7,0.15,3.1) if n[0] == 1: for x in range (6): wood[x].setPosition(0,-20,0) wood[5].setEuler(10,0,0) wood[3].setPosition(1.7,0.05,3) wood[4].setPosition(1.7,0.05,3.2) wood[5].setPosition(1.7,0.15,3.1) if n[0] == 2: for x in range (6): wood[x].setPosition(0,-20,0) n[0] += 1 #スペースキーを一度押すごとに'n'の値を1ずつ増加させる vizact.onkeydown(' ',number)
viz.go()piazza = viz.addChild('piazza.osgb')
########### グローバル変数の初期値の設定 #############POS_HEAD = 0
########### グローバル変数の更新 #############def get_on_timer(): global POS_HEAD POS_HEAD = viz.MainView.getPosition()vizact.ontimer(0.01,get_on_timer)
########### 別の関数で更新されたグローバル変数の読込 #############def print_on_timer(): global POS_HEAD print (POS_HEAD)# print (str(round(POS_HEAD[0],2)),str(round(POS_HEAD[1],2)),str(round(POS_HEAD[2],2))) #適当な桁で四捨五入しておくとよいvizact.ontimer(0.1,print_on_timer)
条件を入力してプログラムを実行する
############ 仮想環境の基本設定 ###########viz.go()viz.fov(80)viz.setMultiSample(4)
ground = viz.addChild('ground.osgb')
############# 壁の作成 ##############
Wall_front= vizshape.addBox(size = [5.0,2.5,0.1])Wall_front.setPosition(0,1.25,2.5) ############ 実験空間の選択肢 ############Height = vizinput.input('身長は何cm?')#開始前に数字を入力し実験空間を選択するEye_Height = int(Height)/100 - 0.15 #int()でHeightを数字情報として扱う#視点高さを入力情報により設定するviz.MainView.setPosition([0,Eye_Height,0])#壁の色を入力情報により設定するchoices = ['red','green','blue','yellow','orange']Wall_Color = viz.choose('壁の色を選択',choices)
if str(choices[Wall_Color]) == 'red': #str()でchoices[Wall_Color]を文字情報として扱う Wall_front.color(viz.RED)elif str(choices[Wall_Color]) == 'green': Wall_front.color(viz.GREEN)elif str(choices[Wall_Color]) == 'blue': Wall_front.color(viz.BLUE)elif str(choices[Wall_Color]) == 'yellow': Wall_front.color(viz.YELLOW)elif str(choices[Wall_Color]) == 'orange': Wall_front.color(viz.ORANGE)
位置座標による処理実行
spin_count = [0] #ドアの開閉記録用spin_count[0] = 0##########PC画面用#################
viz.setMultiSample(4)viz.MainView.setPosition([0,1.4,-5.5])#原点から5.5m手前の1.4m高さからスタート
##########周辺環境の構築##########
viz.clearcolor(0.62,0.8,0.88) #スカイブルーのRGB数値ground = viz.addChild('ground.osgb') #地面の作成ground.setPosition(0,0,-24)
###############玄関ドア作成##################outdoor = viz.addChild('outdoor.osgb')outdoor = vizshape.addBox([1.0,2.2,0.1])outdoor.setPosition(0,1.1,1)#ドアは奥行き1mの場所に設置
pivot = viz.addGroup()pivot.setCenter(-0.5,0,1)outdoor.setParent(pivot)
#右キーでドアを開けるdef OpenDoor(): if spin_count[0] == 0: spin=vizact.spin(0,1,0,70,1.8) pivot.addAction(spin) spin_count[0] = spin_count[0]+1 vizact.onkeydown(viz.KEY_RIGHT,OpenDoor)
#ドアを0.2m越えると自動で閉まるdef CloseDoor(): if viz.MainView.getPosition()[2] >1.2:#位置座標の奥行が1.2mを越えたら if spin_count[0] == 1: spin_count[0] = spin_count[0]-1 spin2=vizact.spin(0,-1,0,70,1.8) pivot.addAction(spin2)
vizact.ontimer(0,CloseDoor)
#WASDキーで視点を操作するviz.cam.setHandler(vizcam.KeyboardCamera())
エリア進入で処理実行
area =vizshape.addBox(size=[1,0.1,1],pos=[0,0,0]) #エリア(可視化するため板を置いている)Wall =vizshape.addBox(size=[5,3,0.1],pos=[0,0,2],color=viz.RED) #前面に壁を作成
############ 0.1秒ごとに行う処理 ################
def onTimer(num): #位置情報を取得 X = viz.MainView.getPosition()[0] Z = viz.MainView.getPosition()[1] Y = viz.MainView.getPosition()[2] if -0.5 < X < 0.5 and -0.5 < Y < 0.5: #エリアに入ったときの処理 if In_Out[0] == 0: #In_Out[0]が0だったら In_Out[0] = 1 #In_Out[0]を1にする
count[0]+=1 #count[0]を+1する Wall.color(viz.GREEN) else: #エリア外の処理 In_Out[0] = 0 #In_Out[0]を0にする Wall.color(viz.RED) #カウント番号を出力 print('count'+'\t'+str(count[0])+'\n') viz.callback(viz.TIMER_EVENT, onTimer)viz.starttimer(1, 0.1, viz.PERPETUAL)############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
エリア進入で処理実行(複数エリア)
area1 =vizshape.addBox(size=[1,0.1,1])#エリア1(可視化するため板を置いている)area1.setPosition(-2,0,0) #エリア1を左側に配置area2 =vizshape.addBox(size=[1,0.1,1])#エリア2(可視化するため板を置いている)area2.setPosition(2,0,0) #エリア2を右側に配置
Wall =vizshape.addBox(size=[5,3,0.1]) #前面に壁を作成Wall.setPosition(0,0,2) Wall.color(viz.RED)
############ 0.1秒ごとに行う処理 ################
def onTimer(num): #位置情報を取得 X = viz.MainView.getPosition()[0] Z = viz.MainView.getPosition()[1] Y = viz.MainView.getPosition()[2] if -2.5 < X < -1.5 and -0.5 < Y < 0.5: #エリア1に入ったときの処理 #countが0ならcountを+1 & Wallを緑に if count[0]==0: count[0]+=1 Wall.color(viz.GREEN) #countが2ならcountを+1 & Wallを青に if count[0]==2: count[0]+=1 Wall.color(viz.BLUE)
if 1.5 < X < 2.5 and -0.5 < Y < 0.5: #エリア2に入ったときの処理 #countが1ならcountを+1 & Wallを黄に if count[0]==1: count[0]+=1 Wall.color(viz.YELLOW) #countが3ならcountを+1 & Wallを白に if count[0]==3: count[0]+=1 Wall.color(viz.WHITE) #カウント番号を出力 data = 'count'+'\t'+str(count[0])+'\n' print(data) viz.callback(viz.TIMER_EVENT, onTimer)viz.starttimer(1, 0.1, viz.PERPETUAL)############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
矢印の作成と操作
テキストの表示
ground = viz.addChild('ground.osgb')viz.fov(80)viz.go()
################# コメント ####################未定義のエラー回避のため事前に空白のコメントを作成しておくとよいtext = 3*[0]for i in range(3): text[i] = viz.addText(' ', pos=[0, 0, 0],parent=viz.WORLD)#テキストは日本語非対応。関数にすると好きな時に実行できるdef TextStart(): text[0] = viz.addText('Start',pos=[-1.5, 1.5, 2],parent=viz.WORLD)#テキスト・位置を指定 text[0].color(viz.WHITE)#色を指定 text[0].setScale([0.3, 0.3, 0.3])#大きさを指定
def TextGoal(): text[1] = viz.addText('Goal', pos = [1.5, 1.5, 2], parent = viz.WORLD)#テキスト・位置を指定 text[1].color(viz.WHITE)#色を指定 text[1].setScale([0.3, 0.3, 0.3])#大きさを指定 def RemoveText(): for i in range(2):#text[0]からtext[1]までを削除 text[i].remove()
vizact.onkeydown('1', TextStart)#'1'でTextStartを実行vizact.onkeydown('2', TextGoal)#'2'でTextGoalを実行vizact.onkeydown('3', RemoveText)#'3'でRemoveTextを実行#{}とformatを利用することで変動する値や、結果の表示も可能def Time(num): text[2].remove() result='Time : "{}s".' text[2] = viz.addText(result.format(round(viz.tick(),1)),pos=[-0.5, 1.5, 2],parent=viz.WORLD) text[2].color(viz.WHITE) text[2].setScale([0.2, 0.2, 0.2])
viz.callback(viz.TIMER_EVENT, Time)viz.starttimer(1, 0.1, viz.PERPETUAL)#矢印をテキストで表示することもできるArrow = viz.addText('↑',pos=[0, 1.0, 1.4],parent=viz.WORLD)Arrow.color(viz.BLACK)Arrow.setEuler([0,90,0])Arrow.setScale([0.4, 0.4, 0.4])
矢印の作成
L = 1.6 #全体の長さ(m)W = 0.1 #太い部分の幅(m)T_L = 0.2 #先端部の長さ(m)T_W = 0.5 #先端部の幅(m)
Col = [1,0,0]#色の指定[1,0,0]は赤############# 周囲環境 ##################
ground = viz.addChild('ground.osgb')viz.MainView.setPosition([0,1.4,0])viz.fov(80)viz.go()
############# 矢印の作成 ##################
#slices=2で平面的な矢印になるArrow = vizshape.addArrow(length = L,radiusRatio = (W/L)/2,tipLengthRatio=T_L/L,tipRadiusRatio=T_W/W,slices=2,color=Col)#setPositionは矢印の先端の座標を指定Arrow.setPosition(0.8,0.8,2)#lookAtは矢印が指し示す座標を指定#roll=90→水平、roll=0→垂直Arrow.lookAt(point=[5,2,2],roll=90)
############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
矢印の長さを距離に応じて変更
def onTimer(num): #位置情報&頭角度情報を取得 X = viz.MainView.getPosition()[0] Y = viz.MainView.getPosition()[2] A = viz.MainView.getEuler()[0] #Arrowの位置を被験者の移動に追従させる Distance = 1.0 #Arrowの先端から被験者までの距離 Arrow_X = math.sin(-A*math.pi/180)*(-Distance)+X Arrow_Y = math.cos(-A*math.pi/180)*(Distance)+Y Arrow.setPosition(Arrow_X,1.4,Arrow_Y) Arrow.lookAt([GoalX,1.4,GoalY],roll=90)
#目標点との距離に応じてArrowの長さ変える #Area_MIN<目標点との距離<Area_MAXのとき、矢印はだんだん短くなる if Area_MIN<math.sqrt(pow((GoalX-X),2)+pow((GoalY-Y),2))<Area_MAX: Arrow.setScale([1,1,1*(math.sqrt(pow((GoalX-X),2)+pow((GoalY-Y),2))-Area_MIN)/(Area_MAX-Area_MIN)]) #目標点との距離<=Area_MINのとき、矢印の長さは0 elif math.sqrt(pow((GoalX-X),2)+pow((GoalY-Y),2))<=Area_MIN: Arrow.setScale(1,1,0)
viz.callback(viz.TIMER_EVENT, onTimer)viz.starttimer(1, 0.1, viz.PERPETUAL)
############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
矢印回答タスク
viz.MainView.setPosition([0,1.0,-2])viz.go()
stop_num=[0]num=[0] #number of command pressed corectlymiss=[0] #number of missed commanddetime = 10 #default time datafile = open("all.csv", mode = 'a') # 新しいファイルを作成Header = 'Time'+','+'Num'+','+'Miss'+'\n'datafile.write(Header)
def WriteData(): data = str(detime)+','+str(round(num[0],1))+','+str(round(miss[0],1))+'\n' print(data) datafile.write(data) ################COMMAND######################key_list=['↑','↓','→','←']command_list=[0,1,2,3] #convert key into 'int'command=[]for x in range(100): #make 400 commands random.shuffle(command_list) for y in command_list: command.append(y) def check_command(key): if stop_num[0] == 0: if key == command[num[0]]: num[0] = num[0]+1 else: miss[0] = miss[0]+1 num[0] = num[0]+1 for s in range(3): text[s].remove() WriteCommand() vizact.onkeydown(viz.KEY_UP,check_command,0)vizact.onkeydown(viz.KEY_DOWN,check_command,1)vizact.onkeydown(viz.KEY_RIGHT,check_command,2)vizact.onkeydown(viz.KEY_LEFT,check_command,3)################COMMAND_TEXT################board = viz.addTexQuad(size = [0.54,0.32],pos=[0,0.95,0.2],color=viz.BLACK)text=[0,0,0]
def WriteCommand(): text[0] = viz.addText(str(key_list[command[num[0]+1]]),pos=[-0.235, 0.9, 0.19],scale=[0.1, 0.1, 0.1],parent=viz.WORLD) #next command text[1] = viz.addText(str(key_list[command[num[0]]]),pos=[-0.035, 0.9, 0.19],scale=[0.15, 0.15, 0.15],parent=viz.WORLD) #current command text[2] = viz.addText(str(key_list[command[num[0]+1]]),pos=[0.165, 0.9, 0.19],scale=[0.1, 0.1, 0.1],parent=viz.WORLD) #next command#######################Text##########################Intro=[0] def OverText(): WriteData() for textnum in range(3): text[textnum].remove() stop_num[0] = 1 Intro[0] = viz.addText('The experiment is over.\nThank you for your cooperation!',pos=[-0.25, 0.95, 0.19],parent=viz.WORLD) Intro[0].setScale([0.03, 0.03, 0.03]) WriteCommand() vizact.ontimer2(detime,0,OverText)
空間操作
空間リセット & 使用可能3D環境まとめ
vizact.onkeydown(' ',ChangeMode)#スペースキーで実験空間をリセット
軸を指定して回転させる
pivot2 = viz.addGroup()pivot2.setCenter(0,0,5)#回転軸2の中心座標を決めるball.setParent(pivot2)#ボールを回転軸2に結び付ける
def Spin_1(): spin=vizact.spin(0,1,0,6,5)#回転方向(x,y,z)&回転速度&回転時間 pivot1.addAction(spin)vizact.ontimer2(10,0,Spin_1)#10秒後に回転軸1を回転
def Spin_2(): spin=vizact.spin(0,1,0,150)#回転方向(x,y,z)&回転速度(時間はデフォルトForever) pivot2.addAction(spin)vizact.ontimer(0,Spin_2)#起動と同時に回転がはじまる
animation path の利用
import vizimport vizactimport vizshapeimport randomimport math
viz.go()viz.setMultiSample(4)viz.fov(80)
################# 地面の生成 ################path_G = viz.addAnimationPath() #仮想のラインを生成path_G.addControlPoint(0,pos=[0,0,0]) #Ground =[] #地面を格納する配列for i in range (0,4): #4回繰り返し Ground.append([]) #地面の配列のなかに ground = viz.addChild('ground.osgb') #指定サイズの地面を viz.link(path_G, ground, offset =(0,0,i*50)) #50mずつずらしながら並べて Ground[i].append(ground) #格納する ################# 左側壁の列の生成 ################path_L = viz.addAnimationPath() #仮想のラインを生成path_L.addControlPoint(0,pos=[-3,1,0]) #仮想のラインを左3m高さ1mに移動
L_WALLS =[] #左側壁を格納する配列for i in range (0,20): #20回繰り返し L_WALLS.append([]) #左側壁の配列のなかに wall = vizshape.addBox(size = [0.2,2.0,2.0]) #指定サイズの壁を viz.link(path_L, wall, offset =(0,0,i*2.5)) #2.5mずつずらしながら並べて L_WALLS[i].append(wall) #格納する ################# 右側壁の列の生成 ################path_R = viz.addAnimationPath() #仮想のラインを生成positions = [[3,1,0], [3,1,10]] #仮想のラインに2つの点を指定for x, pos in enumerate(positions): path_R.addControlPoint(x+1,pos=pos) R_WALLS =[] #右側壁を格納する配列for i in range (0,20): #20回繰り返し R_WALLS.append([]) #右側壁の配列のなかに wall = vizshape.addBox(size = [0.2,2.0,2.0]) #指定サイズの壁を viz.link(path_R, wall, offset =(0,0,i*2.5)) #2.5mずつずらしながら並べて R_WALLS[i].append(wall) #格納する
#pathにリンクさせたものすべてが指定した複数の点に沿って移動していくpath_R.setLoopMode(viz.CIRCULAR) #移動モードを選択path_R.setConstantSpeed(viz.ON,1.45) #移動速度を1.45 m/sに設定vizact.onkeydown(' ', path_R.reset) #pathをリセットする
def Stop_room(): #pathを止める関数 path_R.pause() def Start_room(): #pathを動かす関数 path_R.play() vizact.ontimer(3, Stop_room) #3秒後にpathを止めるvizact.onkeydown(viz.KEY_UP, Start_room) #上キーでpathを動かす
animation path を関数で操作
##########地面の作成##########ground = vizshape.addBox(color=viz.WHITE)ground.setScale(100,0.01,100)ground.setPosition(0,-0.05,0)##################ポール列を動かす#################def columns(Pole_Height,Pole_Span):
#動く道Pをつくる pathP = viz.addAnimationPath() #道Pを秒速1.3m(歩く速さ)で動かす pathP.setConstantSpeed(viz.ON,1.3) #道Pを動かす pathP.play()
#道Pの起点をつくる Path_Height = [0] Path_Height[0] = 0 positionsP = [[0,Path_Height[0],Pole_Span-20],[0,Path_Height[0],-20]]
for x,pos in enumerate(positionsP): pathP.addControlPoint(x+1,pos=pos) #道Pをループさせる pathP.setLoopMode(viz.LOOP)
#ポール列を作成し道Pにリンクさせる ColumnsP =[] for i in range (0,100): #ポールの個数 ColumnsP.append([]) columnP = vizshape.addCylinder(height=Pole_Height,radius=0.06) #ポールは道Pの下にも伸びるため高さ2倍 viz.link(pathP, columnP,offset =(0,Pole_Height/2,Pole_Span*i)) #歩道の厚み分ポールをあげる ColumnsP[i].append(columnP) #ポール列の高さを上げる def Increace():# if Controller[0].getTrigger() > 0.5:#コントローラーとの接続時に使用可能 pathP.clearControlPoints() Path_Height[0] = Path_Height[0]+ 0.01
positionsP = [[0,Path_Height[0],Pole_Span-20],[0,Path_Height[0],-20]] for x,pos in enumerate(positionsP): pathP.addControlPoint(x+1,pos=pos) # vizact.ontimer(0.01,Increace)#コントローラーとの接続時に使用可能 vizact.onkeydown(viz.KEY_UP,Increace)
#ポール列の高さを下げる def Decreace():# if Controller[1].getTrigger() > 0.5:#コントローラーとの接続時に使用可能 pathP.clearControlPoints() Path_Height[0] = Path_Height[0]- 0.01
positionsP = [[0,Path_Height[0],Pole_Span-20],[0,Path_Height[0],-20]] for x,pos in enumerate(positionsP): pathP.addControlPoint(x+1,pos=pos) # vizact.ontimer(0.01,Decreace)#コントローラーとの接続時に使用可能 vizact.onkeydown(viz.KEY_DOWN,Decreace) columns(0.8,1.5)#ポールの高さと間隔を指定して関数を実行
初期アバターを動かす
viz.MainView.setPosition(0,1.5,-5)viz.setMultiSample(4)viz.fov(80)viz.go()#女性アバターの追加female = viz.add('vcc_female.cfg')female.setPosition([0,0,2.5])female.state(11)#走りfemale.setEuler(180, 0, 0) #女性アバターの追加(vizfxを使うと影が反映される)female_fx = vizfx.addAvatar('vcc_female.cfg')female_fx.setPosition([-1,0,2.5])female_fx.state(11)female_fx.speed(0.5)female_fx.setEuler(180, 0, 0) #男性アバタ1ーの追加male = viz.add('vcc_male.cfg')male.setPosition([-5,0,2.5])male.state(1)#立位状態male.setEuler(180, 0, 0) #男性アバタ2ーの追加male2 = viz.add('vcc_male2.cfg')male2.setPosition([5,0,2.5])male2.state(1)#立位状態male2.setEuler(180, 0, 0)
####### 動作の定義 ########spin0 = vizact.spinTo(euler=[0,0,0], speed=400)spin180 = vizact.spinTo(euler=[180,0,0], speed=400)
action1 = vizact.moveTo([5,0,0.5],speed=0.8)action2 = vizact.moveTo([-5,0,0.5],speed=0.8)action3 = vizact.moveTo([0,0,0.5],speed=1.11)action4 = vizact.moveTo([0,0,2.5],speed=1.11)
fem_action = vizact.sequence(action3,spin0,action4,spin180)
def Action(): female.addAction(fem_action) male.addAction(action2) male.state(2)#歩行 male2.addAction(action1) male2.state(2)#歩行vizact.ontimer2(10,0,Action)#起動後10秒で処理が実行
応用テクニック
PC画面に俯瞰図を表示
subView = viz.addView()subView.setPosition([0,10,0]) #高さ10mからの視点subView.setEuler([0,90,0]) #真下を見下ろす角度subWindow = viz.addWindow()subWindow.setSize([0.5,0.5]) #サブウインドウのサイズを変更(全画面に対する比率)subWindow.setPosition([0,1]) #サブウインドウの位置を変更(全画面に対する位置)subWindow.setView( subView )
############# 周囲環境 ##################ground = viz.addChild('ground.osgb')viz.fov(80)viz.go()
ball = viz.add('white_ball.wrl')#俯瞰図用にボールを作成############ 0.1秒ごとに行う処理 ################
def onTimer(num): #位置情報を取得 X = viz.MainView.getPosition()[0] Y = viz.MainView.getPosition()[2] #ボールを位置情報に合わせて動かす moving_ball = vizact.moveTo([X,0.1,Y]) ball.addAction(moving_ball) viz.callback(viz.TIMER_EVENT, onTimer)viz.starttimer(1, 0.1, viz.PERPETUAL)
############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
2点を結ぶ角度の算出
#オブジェクトの作成Bar = vizshape.addBox(size=[0.05,0.05,2])#角度を指定しないとき正面方向に伸びる(重要)Bar.setPosition(0,1.3,2)[X1,Y1]=[-2,2] #目標点1の座標指定[X2,Y2]=[4,4] #目標点2の座標指定
#目標点に円柱を配置して視覚化Pole1 = vizshape.addCylinder(height=2,radius=0.2) #高さ2m,半径0.2mPole1.setPosition(X1,1,Y1)Pole2 = vizshape.addCylinder(height=2,radius=0.2) #高さ2m,半径0.2mPole2.setPosition(X2,1,Y2)
################# 目標点1と目標点2を結ぶ向きにBarを回転させる ################
#目標点1と2を結ぶ直線が、正面方向となす角を求める。2次元ベクトルの内積の公式を利用#正面方向のベクトルと2つの目標点を結ぶベクトルがなす角を求めるcosP = (Y2-Y1)/math.sqrt(pow(X2-X1,2)+pow(Y2-Y1,2))
#目標点1と目標点2の位置関係によってPの符号が変わる #Vizard上で正面からの角は―180°~180°であるが、上の計算式でのPは0°~180°までの値しかとらないためif X2<X1: P = -math.degrees(math.acos(cosP))else: P = math.degrees(math.acos(cosP))Bar.setEuler(P,0,0) print(P)############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
距離一定で追従する
Screen = vizshape.addBox(size=[1,1,0.05])Distance = 2.0 #Screenから被験者までの距離を設定する############ 0.1秒ごとに行う処理 ################
def onTimer(num): #位置情報&頭角度情報を取得 X = viz.MainView.getPosition()[0] Z = viz.MainView.getPosition()[1] Y = viz.MainView.getPosition()[2] A = viz.MainView.getEuler()[0]
#頭角度に合わせてScreenの位置情報を移動 #計算は被験者の位置を中心に座標を回転させる三角関数を使用 Line_X = math.sin(-A*math.pi/180)*(-Distance)+X Line_Y = math.cos(-A*math.pi/180)*(Distance)+Y
Screen.setPosition(Line_X,Z,Line_Y)#位置情報を変更する Screen.setEuler(A,0,0) #頭角度に応じてScreenの角度を変更
viz.callback(viz.TIMER_EVENT, onTimer)viz.starttimer(1, 0.1, viz.PERPETUAL)
############# キーボード操作 ###############keyCam = vizcam.KeyboardCamera() #wasdキーで空間を動かす
☆事前準備2DATA.xlsxのファイルの中#########################################シート1(3つの実験結果が記録されている)A2~C1001に0~10000までの数値が記録済み A B C1 con1 con2 con32 17 8 117
1001 41 24 0 ########################################シート2(30種類の色のデータを記載)A1:1色目のr値、B1:1色目のg値,C1:1色目のb値E1:1色目を適応する最小値、F1:1色目を適応する最大値 A B C D E F1 1 0.07 0.07 8000 10000 2 0.99 0.18 0.10 7724 8000
30 0.88 1 1 0 275
☆事前準備3DATA.xlsxは閉じておく
☆事前準備4DATA.xlsxを実験データと同じフォルダに保存"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
######## 各種インポート #########import vizimport vizshapeimport openpyxl
viz.go()#############################
def Analysis(num): #1000個(10×100)のタイル(square)を作成し配置。 #Square_List[0]~Square_List[999]に格納 Square_List =[] for X in range (10): for Y in range (100): Square = vizshape.addBox(size=[1,0.01,1]) Square.setPosition(X-1,0,Y-0.5) Square.disable(viz.LIGHTING) Square_List.append(Square) wb = openpyxl.load_workbook('DATA.xlsx')#読み込むExcelファイル ws1 = wb.worksheets[0]#ws1=Excelのシート1(3つの実験結果が記録されている) ws2 = wb.worksheets[1]#ws2=Excelのシート2(30種の色のでデータを記載) #各行row(2~1001)に対して、列col(1~3)の値を取得してvaluesのリストに格納する #values[0]:1列目のデータ、values[1]:2列目のデータ、values[0]:3列目のデータ row_num = 1 for row in ws1.iter_rows(min_row=2): row_num += 1 values = [] for col in row: values.append(col.value) for k in range(30): #シート2の値を利用してタイルに色をつける #Analysis実行時に指定したnumによってシート1で参照する列が異なる #シート2(Ek)<シート1の値<シート2(Fk)のとき、r=シート2(Ak),g=シート2(Bk),b=シート2(Ck) #k(0~29)なので参照する行はk+1(1~30) if ws2.cell(k+1,5).value < values[num-1]<= ws2.cell(k+1,6).value: r = ws2.cell(k+1,1).value g = ws2.cell(k+1,2).value b = ws2.cell(k+1,3).value #タイル(square)に色をつける #Square_List(0~999)に対してrow_num(2~1001)であるため-2 Square_List[row_num-2].color([r,g,b]) ####### 参照する条件を選択する(1~3) ##########def Change(keyID):
children = viz.MainScene.getChildren() for child in children: child.remove() if keyID == 1: Analysis(1) elif keyID ==2: Analysis(2) elif keyID ==3: Analysis(3) def quit_analysis(): expelimental_data.close() viz.quit()
############ 初期設定 #############Analysis(1)
############# キーボード操作 #############vizact.onkeydown('1',Change,keyID=1)vizact.onkeydown('2',Change,keyID=2)vizact.onkeydown('3',Change,keyID=3)vizact.onkeydown('k',quit_analysis)
ブランコ(振り子&視点操作)
viz.addChild('piazza.osgb')viz.clearcolor(viz.SLATE)viz.go()
###########VIVE###################import steamvr### Setup SteamVR HMD#hmd = steamvr.HMD()#if not hmd.getSensor():# sys.exit('SteamVR HMD not detected')### Setup navigation node and link to main view#navigationNode = viz.addGroup()#viewLink = viz.link(navigationNode, viz.MainView)#viewLink.preMultLinkable(hmd.getSensor())
CYCLES_PER_SEC = 0.15 #周期AMPLITUDE = 60.0 #振幅#支柱column_1 = vizshape.addCylinder(height = 3.0,radius = 0.05,pos = [0, 1.5, 0],color = viz.RED)column_2 = vizshape.addCylinder(height = 3.0,radius = 0.05,pos = [0, 1.5, 0],color = viz.RED,parent=column_1)column_2.setPosition([0, 0, 2])#上の棒Bar = vizshape.addCylinder(height = 2.0,radius = 0.05,pos = [0, 1.5, 0],color = viz.BLUE ,parent=column_1)Bar.setAxisAngle([1,0,0, 90])Bar.setPosition([0, 1.5, 1])#緑のジョイントj1 = viz.addChild('joint.wrl',pos = [0, 0.5, 0],parent=Bar)j2 = viz.addChild('joint.wrl',pos = [0, -0.5, 0],parent=Bar)j1.setAxisAngle([1,0,0, 90])j2.setAxisAngle([1,0,0, 90])#振り棒c4 = viz.addChild('cylinder.wrl',parent=j1)c5 = viz.addChild('cylinder.wrl',parent=j2)c4.setScale([0.5,5,0.5])c5.setScale([0.5,5,0.5])#乗り台plate = vizshape.addBox(size=[0.5,0.01,2],parent=c4)plate.setPosition([0,0.5,1])plate.setAxisAngle([0,1,0, 180])########### 乗り台に視点を合わせる #############viewLink = viz.link(plate,viz.MainView,srcFlag=viz.ABS_GLOBAL)viewLink.preEuler( [270, 10, 180] )viewLink.preTrans( [0, 0.3, 0] )########### 振り子運動を実行 ##############def AnimateNode(): angle = math.sin(viz.tick() * CYCLES_PER_SEC * 2*math.pi) * AMPLITUDE c4.setAxisAngle([0,0,1, angle]) c5.setAxisAngle([0,0,1, angle])vizact.ontimer(0,AnimateNode)
コントローラーでスライダーを動かす
x = [0]x[0]=-Size/2 #バーの初期値を設定
viz.go() ######## HMD装着 ######## import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
navigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
###### コントローラー接続 ######Controller = steamvr.getControllerList()for controller in steamvr.getControllerList(): #Create model for controller controller = controller controller.model = controller.addModel() controller.model.disable(viz.INTERSECTION) controller.distance = 1.0 viz.link(controller, controller.model)
######## スライダー作成 #########シリンダーの作成 cylinder = vizshape.addCylinder(height = Size,radius = 0.02,axis = vizshape.AXIS_X, pos=[0,1.6,3])#バーの配置Box = vizshape.addBox(size=(0.1,0.5,0.1))Box.setPosition(-Size/2,1.6,3)
### コントローラーでスライダーを動かす ###def increase(): if Controller[0].getTrackpad()[0] > 0.7: #トラックパッド右で増加 if x[0]<Size/2: x[0] = x[0]+0.01 Box.setPosition(x[0],1.6,3) print('Increace', round(x[0]/Size+1/2,3)) vizact.ontimer(0.01,increase)
def decrease(): if Controller[0].getTrackpad()[0] < -0.2: #トラックパッド左で減少 if x[0]>-Size/2: x[0] = x[0]-0.01 Box.setPosition(x[0],1.6,3) print('Decreasse', round(x[0]/Size+1/2,3)) vizact.ontimer(0.01,decrease)
############# キーボード操作 ###############datafile = open('slider_'+datetime.datetime.today().strftime("%Y%m%d")+'.csv','a')Header = 'Sub'+','+'Num'+','+'Value'+'\n'datafile.write(Header)
def WriteData(): data = str(Sub)+','+str(Num)+','+str(round(x[0]/4+1/2,3))+'\n' datafile.write(data) datafile.close() viz.quit() vizact.onkeydown(' ',WriteData) #スペースキーで実験を終了
応用テクニック: ナビゲーション
目的地に向かう矢印を常に表示する
This Script Based on using the following equipments. - WorldViz Vizard 7.0 over '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#######################################################################################
import vizimport vizactimport vizshapeimport viztrackerimport vizproximityimport randomimport mathimport csvimport datetimeimport vizinputimport timeimport viztaskimport vizmatimport projectorimport sysimport vizcamimport vizfximport vizconnectimport vizinfo
viz.go()viz.setMultiSample(4)viz.fov(80)
viz.MainView.setPosition([-0.5,1.5,0.5])viz.MainView.setEuler([0,0,0])#viz.MainView.collision(viz.ON)
# Add a white directional light pointing down light = vizfx.addDirectionalLight(euler=(0,90,0), color=viz.WHITE)
###########VIVE###################import steamvr### Setup SteamVR HMD#hmd = steamvr.HMD()#if not hmd.getSensor():# sys.exit('SteamVR HMD not detected')### Setup navigation node and link to main view#navigationNode = viz.addGroup()#viewLink = viz.link(navigationNode, viz.MainView)#viewLink.preMultLinkable(hmd.getSensor())
################################## グローバル変数一覧 #####################################POS_HEAD = [0] #頭位置[x,y,z]POS_HEAD[0] = 0ORI_HEAD = [0] #頭角度[r,p,y]ORI_HEAD[0] = 0
#print POS_HEAD
reset_time = [0] #時刻リセット用変数reset_time[0] = 0
flagLogging = [0] #データ記録フラグflagLogging[0] = False
###############データ出力の準備 #############EVENT_TIMER_ID = 1 #イベントチェックタイマーIDEVENT_TIMER_PERIOD = 0.1 #チェック間隔[s]PROCESS_TIMER_ID = 2 #データ保存タイマーIDPROCESS_TIMER_PERIOD = 0.016666666 #データ保存間隔[s] ≒ 60Hzoutfile = None #出力ファイルオブジェクト(内部用)outcsv = None #CSVフォーマットオブジェクト(内部用)start_time = time.time() #経過時間(内部用)
#subject = 1 #被験者識別番号、実験開始前に被験者毎に設定する##FileName='tanabe_experiment'+datetime.datetime.today().strftime("%Y%m%d")+'_Sub'+str(subject)+'.txt'#Header ='Subject'+'\t'+'Lap_time'+'\t'#Header +='PosX'+'\t'+'PosY'+'\t'+'PosZ'+'\t'+'Yaw'+'\t'+'Pitch'+'\t'+'Roll'+'\n'#expelimental_data = open(FileName,'a') #expelimental_data.write(Header)
################### 左上に検証用サブウィンドウを作成 ####################UpperLeftWindow = viz.addWindow(pos=(0,1.0),size=(0.25,0.25))UpperLeftWindow.visible(0,viz.SCREEN)BirdView = viz.addView() #Create a new viewpointUpperLeftWindow.setView(BirdView) #Attach the bird's eye view to the upper left windowBirdView.setPosition([-2,6,2]) #Move the view above the center of the roomBirdView.setEuler([90,90,90]) #Rotate the view so that it looks downUpperLeftWindow.fov(60)
#MainViewのポジションを赤いConeにリンクさせるview = viz.MainViewCone = vizshape.addCone(radius=0.1,height=0.3, axis=vizshape.AXIS_Z,color = viz.RED)Cone.renderOnlyToWindows([UpperLeftWindow])viz.link(view,Cone)
################# 軌跡レンダ ################viz.startLayer(viz.LINE_STRIP)viz.vertexColor(viz.YELLOW)lines = viz.endLayer(parent=viz.ORTHO,scene=UpperLeftWindow)
lines.dynamic()
def UpdatePath():
# Get main view position in bird eye window pixel coordinates x,y,z = UpperLeftWindow.worldToScreen(viz.MainView.getPosition(),mode=viz.WINDOW_PIXELS)
# Get position of last line vertex lx,ly,lz = lines.getVertex(-1)
# Add new vertex if current position is different from last position if x != lx or y != ly: lines.addVertex([x,y,0.0])
vizact.ontimer(0,UpdatePath)
#スペースキーで軌跡削除vizact.onkeydown('',lines.clearVertices)
################# 地面の生成 ################ground = viz.addChild('ground.osgb')ground.setPosition([0,0,0])
################# 迷路の生成 ################wall1 = vizshape.addBox(size = [4,2,0.05])wall2 = vizshape.addBox(size = [0.05,2,4])wall3 = vizshape.addBox(size = [0.05,2,4])wall4 = vizshape.addBox(size = [4,2,0.05])wall5 = vizshape.addBox(size = [0.05,2,3])wall6 = vizshape.addBox(size = [2,2,0.05])wall7 = vizshape.addBox(size = [0.05,2,2])wall8 = vizshape.addBox(size = [0.05,2,1])wall9 = vizshape.addBox(size = [1,2,0.05])
wall1.setPosition([-2,1,0])wall2.setPosition([0,1,2])wall3.setPosition([-4,1,2])wall4.setPosition([-2,1,4])wall5.setPosition([-1,1,1.5])wall6.setPosition([-2,1,1])wall7.setPosition([-2,1,3])wall8.setPosition([-3,1,2.5])wall9.setPosition([-3.5,1,2])
################# ゴールの生成 ################goal = viz.add('logo.wrl',pos=[-3.5,1.2,2.5],euler=[0,0,0],scale=[0.2,0.2,0.2])
####################################被験者がエリア内にいる間矢印を非表示にする######################################################矢印を配置#############cone = viz.addChild('tut_cone.wrl')cone.setScale([0.08,0.08,0.08])cone.color([255,212,0])cone.setEuler(0,90,0)
#Copy main view transform to arrow'stransform every frame #viz.MainView is source object, arrow is destination object coneLink = viz.link(viz.MainView, cone, mask=viz.LINK_POS ) coneLink.preTrans([0, 0.2, 0.5])
#目的地の方向に矢印を回転させるdef HeadingArrow(): POS = cone.getPosition()# print POS GOAL_POS =[-3.5,0,2.5] if GOAL_POS[2] > POS[2]: DEG = math.atan((POS[0]-GOAL_POS[0])/(GOAL_POS[2]-POS[2]))*(180/math.pi) cone.setEuler(90-DEG,90,90) if GOAL_POS[2] < POS[2]: DEG = math.atan((POS[0]-GOAL_POS[0])/(POS[2]-GOAL_POS[2]))*(180/math.pi) cone.setEuler(DEG-90,90,90) vizact.ontimer(0,HeadingArrow)
#############センサー追加準備##############Create proximity manager and set debug on. Toggle debug with d keymanager = vizproximity.Manager()manager.setDebug(viz.ON)debugEventHandle = vizact.onkeydown('d',manager.setDebug,viz.TOGGLE)
#Add main viewpoint as proximity targettarget = vizproximity.Target(viz.MainView)manager.addTarget(target)
#############センサーを追加する#############verts = [ [-1,2], [-2,2], [-2,3], [-3,3], [-3,1], [-1,1] ]sensor = vizproximity.Sensor( vizproximity.PolygonArea(verts,offset=[0,0]), None )
SEN =[0]SEN[0] =True
#経路案内を消すdef Enter(e): cone.visible(viz.OFF) SEN[0] = False# text[0].remove()
#経路案内を出すdef Exit(e): cone.visible(viz.ON) SEN[0] = True
manager.addSensor(sensor)manager.onEnter(sensor, Enter)manager.onExit(sensor, Exit)
#目的地までの距離を表示d = 0text= [0] #グローバルに定義 text[0] = viz.addText(str(d) + 'm',pos=[2, 0.6, 3.5],scale=[0.05,0.05,0.05],parent=viz.WORLD)
def MeasureDistance(): if SEN[0] == True: text[0].remove() POS_NOW = viz.MainView.getPosition() p1 = [POS_NOW[0],0,POS_NOW[2]] p2 = [-3.5,0,2.5] distance = vizmat.Distance(p1,p2) d = round(distance,2) print(d) text[0] = viz.addText(str(d) + 'm',pos=[2, 0.6, 3.5],scale=[0.05,0.05,0.05],parent=viz.WORLD) textLink = viz.link(viz.MainView, text[0]) textLink.preTrans( [0, -0.1, 0.2] )
vizact.ontimer(0.1,MeasureDistance)
############################### データ出力 ######################################def onTimer(num): # #データを取得し、ファイルへ出力&マスクを移動する# curr_time = time.clock() - reset_time[0]## # POS_HEAD[0] = viz.MainView.getPosition() #頭の位置を取得# ORI_HEAD[0] = viz.MainView.getEuler() #頭の回転角を取得# # data = str(subject)+'\t'+str(round(curr_time,3))+'\t'# data += str(round(POS_HEAD[0][0],3))+'\t'+str(round(POS_HEAD[0][1],3))+'\t'+str(round(POS_HEAD[0][2],3))+'\t'# data += str(round(ORI_HEAD[0][0],3))+'\t'+str(round(ORI_HEAD[0][1],3))+'\t'+str(round(ORI_HEAD[0][2],3))+'\n'# # print data# # expelimental_data.write(data)## prev_time = curr_time##viz.callback(viz.TIMER_EVENT, onTimer)##viz.starttimer(EVENT_TIMER_ID, EVENT_TIMER_PERIOD, viz.PERPETUAL)################################################################################
目的地までの経路をラインで指示する
This Script Based on using the following equipments. - WorldViz Vizard 5.0 over '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#######################################################################################
import vizimport vizactimport vizshapeimport viztrackerimport vizproximityimport randomimport mathimport csvimport datetimeimport vizinputimport timeimport viztaskimport vizmatimport projectorimport sysimport vizcamimport vizfximport vizconnectimport vizinfo
viz.go()viz.setMultiSample(4)viz.fov(80)
viz.MainView.setPosition([-2.5,1.5,3.5])viz.MainView.setEuler([-90,0,0])#viz.MainView.collision(viz.ON)
# Add a white directional light pointing down light = vizfx.addDirectionalLight(euler=(0,90,0), color=viz.WHITE)
###########VIVE###################import steamvr### Setup SteamVR HMD#hmd = steamvr.HMD()#if not hmd.getSensor():# sys.exit('SteamVR HMD not detected')### Setup navigation node and link to main view#navigationNode = viz.addGroup()#viewLink = viz.link(navigationNode, viz.MainView)#viewLink.preMultLinkable(hmd.getSensor())
################################## グローバル変数一覧 #####################################POS_HEAD = [0] #頭位置[x,y,z]POS_HEAD[0] = 0ORI_HEAD = [0] #頭角度[r,p,y]ORI_HEAD[0] = 0
#print POS_HEAD
reset_time = [0] #時刻リセット用変数reset_time[0] = 0
flagLogging = [0] #データ記録フラグflagLogging[0] = False
###############データ出力の準備 #############EVENT_TIMER_ID = 1 #イベントチェックタイマーIDEVENT_TIMER_PERIOD = 0.1 #チェック間隔[s]PROCESS_TIMER_ID = 2 #データ保存タイマーIDPROCESS_TIMER_PERIOD = 0.016666666 #データ保存間隔[s] ≒ 60Hzoutfile = None #出力ファイルオブジェクト(内部用)outcsv = None #CSVフォーマットオブジェクト(内部用)start_time = time.time() #経過時間(内部用)
#subject = 1 #被験者識別番号、実験開始前に被験者毎に設定する##FileName='tanabe_experiment'+datetime.datetime.today().strftime("%Y%m%d")+'_Sub'+str(subject)+'.txt'#Header ='Subject'+'\t'+'Lap_time'+'\t'#Header +='PosX'+'\t'+'PosY'+'\t'+'PosZ'+'\t'+'Yaw'+'\t'+'Pitch'+'\t'+'Roll'+'\n'#expelimental_data = open(FileName,'a') #expelimental_data.write(Header)
################### 左上に検証用サブウィンドウを作成 ####################UpperLeftWindow = viz.addWindow(pos=(0,1.0),size=(0.25,0.25))UpperLeftWindow.visible(0,viz.SCREEN)BirdView = viz.addView() #Create a new viewpointUpperLeftWindow.setView(BirdView) #Attach the bird's eye view to the upper left windowBirdView.setPosition([-2,6,2]) #Move the view above the center of the roomBirdView.setEuler([90,90,90]) #Rotate the view so that it looks downUpperLeftWindow.fov(60)
#MainViewのポジションを赤いConeにリンクさせるview = viz.MainViewCone = vizshape.addCone(radius=0.1,height=0.3, axis=vizshape.AXIS_Z,color = viz.RED)Cone.renderOnlyToWindows([UpperLeftWindow])viz.link(view,Cone)
################# 軌跡レンダ ################viz.startLayer(viz.LINE_STRIP)viz.vertexColor(viz.YELLOW)lines = viz.endLayer(parent=viz.ORTHO,scene=UpperLeftWindow)
lines.dynamic()
def UpdatePath():
# Get main view position in bird eye window pixel coordinates x,y,z = UpperLeftWindow.worldToScreen(viz.MainView.getPosition(),mode=viz.WINDOW_PIXELS)
# Get position of last line vertex lx,ly,lz = lines.getVertex(-1)
# Add new vertex if current position is different from last position if x != lx or y != ly: lines.addVertex([x,y,0.0])
vizact.ontimer(0,UpdatePath)
#スペースキーで軌跡削除vizact.onkeydown('',lines.clearVertices)
################# 地面の生成 ################ground = viz.addChild('ground.osgb')ground.setPosition([0,0,0])
################# 迷路の生成 ################wall1 = vizshape.addBox(size = [4,2,0.05])wall2 = vizshape.addBox(size = [0.05,2,4])wall3 = vizshape.addBox(size = [0.05,2,4])wall4 = vizshape.addBox(size = [4,2,0.05])wall5 = vizshape.addBox(size = [3,2,0.05])wall6 = vizshape.addBox(size = [0.05,2,2])wall7 = vizshape.addBox(size = [2,2,0.05])wall8 = vizshape.addBox(size = [1,2,0.05])wall9 = vizshape.addBox(size = [0.05,2,1])
wall1.setPosition([-2,1,0])wall2.setPosition([0,1,2])wall3.setPosition([-4,1,2])wall4.setPosition([-2,1,4])wall5.setPosition([-1.5,1,1])wall6.setPosition([-1,1,2])wall7.setPosition([-3,1,2])wall8.setPosition([-2.5,1,3])wall9.setPosition([-2,1,3.5])
################# ゴールの生成 ################goal = viz.add('logo.wrl',pos=[-0.5,1.2,0.5],euler=[-90,0,0],scale=[0.2,0.2,0.2])
####################################被験者がエリア内にいる時に経路案内のラインを非表示にする######################################################ルートラインを配置##############inport skethupviz.setOption('viz.model.apply_collada_scale',1) route = viz.add('route.dae')route.setPosition([-0.5,0.5,0.5])
#############センサー追加準備##############Create proximity manager and set debug on. Toggle debug with d keymanager = vizproximity.Manager()manager.setDebug(viz.ON)debugEventHandle = vizact.onkeydown('d',manager.setDebug,viz.TOGGLE)
#Add main viewpoint as proximity targettarget = vizproximity.Target(viz.MainView)manager.addTarget(target)
#############センサーを追加する#############verts = [ [-1,4], [-1,2], [-3,2], [-3,3], [-2,3], [-2,4] ]sensor = vizproximity.Sensor( vizproximity.PolygonArea(verts,offset=[0,0]), None )
#ルートラインを消すdef Enter(e): route.visible(viz.OFF) #ルートラインを出すdef Exit(e): route.visible(viz.ON) manager.addSensor(sensor)manager.onEnter(sensor, Enter)manager.onExit(sensor, Exit)
############################### データ出力 ######################################def onTimer(num): # #データを取得し、ファイルへ出力&マスクを移動する# curr_time = time.clock() - reset_time[0]## # POS_HEAD[0] = viz.MainView.getPosition() #頭の位置を取得# ORI_HEAD[0] = viz.MainView.getEuler() #頭の回転角を取得# # data = str(subject)+'\t'+str(round(curr_time,3))+'\t'# data += str(round(POS_HEAD[0][0],3))+'\t'+str(round(POS_HEAD[0][1],3))+'\t'+str(round(POS_HEAD[0][2],3))+'\t'# data += str(round(ORI_HEAD[0][0],3))+'\t'+str(round(ORI_HEAD[0][1],3))+'\t'+str(round(ORI_HEAD[0][2],3))+'\n'# # print data# # expelimental_data.write(data)## prev_time = curr_time##viz.callback(viz.TIMER_EVENT, onTimer)##viz.starttimer(EVENT_TIMER_ID, EVENT_TIMER_PERIOD, viz.PERPETUAL)################################################################################
コーナーでのみ経路を矢印で指示する
This Script Based on using the following equipments. - WorldViz Vizard 7.0 over '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#######################################################################################
import vizimport vizactimport vizshapeimport viztrackerimport vizproximityimport randomimport mathimport csvimport datetimeimport vizinputimport timeimport viztaskimport vizmatimport projectorimport sysimport vizcamimport vizfximport vizconnectimport vizinfo
viz.go()viz.setMultiSample(4)viz.fov(80)
viz.MainView.setPosition([-0.5,1.5,0.5])viz.MainView.setEuler([-90,0,0])#viz.MainView.collision(viz.ON)
# Add a white directional light pointing down light = vizfx.addDirectionalLight(euler=(0,90,0), color=viz.WHITE)
###########VIVE###################import steamvr### Setup SteamVR HMD#hmd = steamvr.HMD()#if not hmd.getSensor():# sys.exit('SteamVR HMD not detected')### Setup navigation node and link to main view#navigationNode = viz.addGroup()#viewLink = viz.link(navigationNode, viz.MainView)#viewLink.preMultLinkable(hmd.getSensor())
################################## グローバル変数一覧 #####################################POS_HEAD = [0] #頭位置[x,y,z]POS_HEAD[0] = 0ORI_HEAD = [0] #頭角度[r,p,y]ORI_HEAD[0] = 0
#print POS_HEAD
reset_time = [0] #時刻リセット用変数reset_time[0] = 0
flagLogging = [0] #データ記録フラグflagLogging[0] = False
###############データ出力の準備 #############EVENT_TIMER_ID = 1 #イベントチェックタイマーIDEVENT_TIMER_PERIOD = 0.1 #チェック間隔[s]PROCESS_TIMER_ID = 2 #データ保存タイマーIDPROCESS_TIMER_PERIOD = 0.016666666 #データ保存間隔[s] ≒ 60Hzoutfile = None #出力ファイルオブジェクト(内部用)outcsv = None #CSVフォーマットオブジェクト(内部用)start_time = time.time() #経過時間(内部用)
#subject = 1 #被験者識別番号、実験開始前に被験者毎に設定する##FileName='tanabe_experiment'+datetime.datetime.today().strftime("%Y%m%d")+'_Sub'+str(subject)+'.txt'#Header ='Subject'+'\t'+'Lap_time'+'\t'#Header +='PosX'+'\t'+'PosY'+'\t'+'PosZ'+'\t'+'Yaw'+'\t'+'Pitch'+'\t'+'Roll'+'\n'#expelimental_data = open(FileName,'a') #expelimental_data.write(Header)
################### 左上に検証用サブウィンドウを作成 ####################UpperLeftWindow = viz.addWindow(pos=(0,1.0),size=(0.25,0.25))UpperLeftWindow.visible(0,viz.SCREEN)BirdView = viz.addView() #Create a new viewpointUpperLeftWindow.setView(BirdView) #Attach the bird's eye view to the upper left windowBirdView.setPosition([-2,6,2]) #Move the view above the center of the roomBirdView.setEuler([90,90,90]) #Rotate the view so that it looks downUpperLeftWindow.fov(60)
#MainViewのポジションを赤いConeにリンクさせるview = viz.MainViewCone = vizshape.addCone(radius=0.1,height=0.3, axis=vizshape.AXIS_Z,color = viz.RED)Cone.renderOnlyToWindows([UpperLeftWindow])viz.link(view,Cone)
################# 軌跡レンダ ################viz.startLayer(viz.LINE_STRIP)viz.vertexColor(viz.YELLOW)lines = viz.endLayer(parent=viz.ORTHO,scene=UpperLeftWindow)
lines.dynamic()
def UpdatePath():
# Get main view position in bird eye window pixel coordinates x,y,z = UpperLeftWindow.worldToScreen(viz.MainView.getPosition(),mode=viz.WINDOW_PIXELS)
# Get position of last line vertex lx,ly,lz = lines.getVertex(-1)
# Add new vertex if current position is different from last position if x != lx or y != ly: lines.addVertex([x,y,0.0])
vizact.ontimer(0,UpdatePath)
##スペースキーで軌跡削除#vizact.onkeydown('',lines.clearVertices)
################# 地面の生成 ################ground = viz.addChild('ground.osgb')ground.setPosition([0,0,0])
################# 迷路の生成 ################wall1 = vizshape.addBox(size = [4,2,0.05])wall2 = vizshape.addBox(size = [0.05,2,4])wall3 = vizshape.addBox(size = [0.05,2,4])wall4 = vizshape.addBox(size = [4,2,0.05])wall5 = vizshape.addBox(size = [3,2,0.05])wall6 = vizshape.addBox(size = [0.05,2,2])wall7 = vizshape.addBox(size = [2,2,0.05])wall8 = vizshape.addBox(size = [1,2,0.05])wall9 = vizshape.addBox(size = [0.05,2,1])
wall1.setPosition([-2,1,0])wall2.setPosition([0,1,2])wall3.setPosition([-4,1,2])wall4.setPosition([-2,1,4])wall5.setPosition([-1.5,1,1])wall6.setPosition([-1,1,2])wall7.setPosition([-3,1,2])wall8.setPosition([-2.5,1,3])wall9.setPosition([-2,1,3.5])
################# スタート・ゴールの生成 ################start = viz.add('logo.wrl',pos=[-1,1.2,0.5],euler=[-90,0,0],scale=[0.2,0.2,0.2])start.visible(viz.OFF)
goal = viz.add('logo.wrl',pos=[-2.5,1.2,3.5],euler=[90,0,0],scale=[0.2,0.2,0.2])
####################################被験者がエリア内にいる時に矢印ナビゲーションを表示する######################################################矢印を配置##############inport skethupviz.setOption('viz.model.apply_collada_scale',1)arrow_straight1 = viz.add('arrow_straight.dae') arrow_straight1.setPosition([-1.5,0.5,0.5])arrow_straight1.setEuler([-90,0,0])#arrow_straight1.visible(viz.OFF)arrow_straight2 = arrow_straight1.clone(pos=[-0.5,0.5,2.5])arrow_straight2.setEuler([180,0,0])arrow_straight2.visible(viz.OFF)arrow_right1 = viz.add('arrow.dae')arrow_right1.setPosition([-3,0.5,0.5])arrow_right1.setEuler([-90,0,0])arrow_right1.visible(viz.OFF) arrow_right2 = arrow_right1.clone(pos=[-3.5,0.5,1])arrow_right2.visible(viz.OFF)arrow_right3 = arrow_right2.clone(pos=[-3.5,0.5,3])arrow_right3.visible(viz.OFF)
#############センサー追加準備##############Create proximity manager and set debug on. Toggle debug with d keymanager = vizproximity.Manager()manager.setDebug(viz.ON)debugEventHandle = vizact.onkeydown('d',manager.setDebug,viz.TOGGLE)
#Add main viewpoint as proximity targettarget = vizproximity.Target(viz.MainView)manager.addTarget(target)
#############右折用センサーを追加する#############sensor1 = vizproximity.Sensor( vizproximity.RectangleArea([1,1],center=[-2.5,0.5]), None )
#矢印を消すdef EnterR1(e): arrow_right1.visible(viz.ON) #矢印を出すdef ExitR1(e): arrow_right1.visible(viz.OFF)
manager.addSensor(sensor1)manager.onEnter(sensor1, EnterR1)manager.onExit(sensor1, ExitR1)
sensor2 = vizproximity.Sensor( vizproximity.RectangleArea([1,1],center=[-3.5,0.5]), None )
#矢印を消すdef EnterR2(e): arrow_right2.visible(viz.ON) #矢印を出すdef ExitR2(e): arrow_right2.visible(viz.OFF)
manager.addSensor(sensor2)manager.onEnter(sensor2, EnterR2)manager.onExit(sensor2, ExitR2)
sensor3 = vizproximity.Sensor( vizproximity.RectangleArea([1,1],center=[-3.5,2.5]), None )
#矢印を消すdef EnterR3(e): arrow_right3.visible(viz.ON) #矢印を出すdef ExitR3(e): arrow_right3.visible(viz.OFF) manager.addSensor(sensor3)manager.onEnter(sensor3, EnterR3)manager.onExit(sensor3, ExitR3)
#############直進用センサーを追加する#############sensor4 = vizproximity.Sensor( vizproximity.RectangleArea([1,1],center=[-1.5,0.5]), None )
#矢印を消すdef EnterS1(e): arrow_straight1.visible(viz.ON) #矢印を出すdef ExitS1(e): arrow_straight1.visible(viz.OFF)
manager.addSensor(sensor4)manager.onEnter(sensor4, EnterS1)manager.onExit(sensor4, ExitS1)
############################### データ出力 #####################################verts = [ [-1,4], [-1,2], [-3,2], [-3,3], [-2,3], [-2,4] ]sensor_timer = vizproximity.Sensor( vizproximity.PolygonArea(verts,offset=[0,0]), None )
#タイマーリセット#def Enter(e):# route.visible(viz.OFF)# ##タイマーリセット#def Exit(e):# route.visible(viz.ON)# #manager.addSensor(sensor)#manager.onEnter(sensor, Enter)#manager.onExit(sensor, Exit)
#def onTimer(num): # #データを取得し、ファイルへ出力&マスクを移動する# curr_time = time.clock() - reset_time[0]## # POS_HEAD[0] = viz.MainView.getPosition() #頭の位置を取得# ORI_HEAD[0] = viz.MainView.getEuler() #頭の回転角を取得# # data = str(subject)+'\t'+str(round(curr_time,3))+'\t'# data += str(round(POS_HEAD[0][0],3))+'\t'+str(round(POS_HEAD[0][1],3))+'\t'+str(round(POS_HEAD[0][2],3))+'\t'# data += str(round(ORI_HEAD[0][0],3))+'\t'+str(round(ORI_HEAD[0][1],3))+'\t'+str(round(ORI_HEAD[0][2],3))+'\n'# # print data# # expelimental_data.write(data)## prev_time = curr_time##viz.callback(viz.TIMER_EVENT, onTimer)##viz.starttimer(EVENT_TIMER_ID, EVENT_TIMER_PERIOD, viz.PERPETUAL)################################################################################
手元にスマホライクなマップを表示する_Basic
This Script Based on using the following equipments. - WorldViz Vizard 7.0 over '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''#######################################################################################import vizimport vizshape
viz.go()viz.setMultiSample(4)viz.fov(80)ground = viz.addChild('ground.osgb')
################# Following Display ##################### Video as Texturevideo = viz.addRenderTexture() #Looking Down Camera SettingLookDownCam = viz.addRenderNode()LookDownCam.setEuler( [0, 90, 0] )Camera_Link = viz.link(viz.MainView,LookDownCam)Camera_Link.preTrans( [0, 10, 0] )
# Heading upCamera_Link.preEuler( [0, 90, 0] )
# North_UP#Camera_Link.setMask(viz.LINK_POS)
LookDownCam.setInheritView(False)LookDownCam.setRenderTexture(video)
#Following Display SettingFollowing_Display = vizshape.addPlane(size = [0.04,0.04])Following_Display.texture(video)
Display_Link = viz.link( viz.MainView,Following_Display)Display_Link.preTrans( [0.04, -0.04, 0.1] ) Display_Link.preEuler( [0, -80, 0] )
#Following Display SettingDirection_Cone = vizshape.addCone(radius=0.8,height=1)coneLink = viz.link(LookDownCam,Direction_Cone)coneLink.preTrans( [0, 0, 10] )
手元にスマホライクなマップを表示する_Basic_R
This Script Based on using the following equipments.- WorldViz Vizard 7.0 over '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''####################################################
import vizimport vizshape
viz.go()viz.setMultiSample(4)viz.fov(80)ground = viz.addChild('ground.osgb')
# Set a Looking Down CameraLookDownCam = viz.addRenderNode()LookDownCam.setInheritView(False)LookDownCam.setEuler( [0, 90, 0] )
# Link the camera to MainView only in position Camera_Link = viz.link(viz.MainView,LookDownCam)Camera_Link.setMask(viz.LINK_POS)Camera_Link.postTrans( [0, 10, 0] )
# Set and Link Display with MainviewFollowing_Display = vizshape.addPlane(size = [0.04,0.04])Display_Link = viz.link( viz.MainView,Following_Display)Display_Link.preTrans( [0.04, -0.04, 0.1] ) Display_Link.preEuler( [0, -80, 0] )
# Set View from Camera as a texture on Dispaly video = viz.addRenderTexture()LookDownCam.setRenderTexture(video)Following_Display.texture(video)
# Set a arrow that indicate the direction of MainviewDirection_Arrow = vizshape.addArrow(length=0.4,radiusRatio=0.2, tipLengthRatio=0.99)Direction_Arrow.renderOnlyToRenderNodes([LookDownCam], excludeMainPass = True)Arrow_Link = viz.link(viz.MainView,Direction_Arrow)Arrow_Link.postTrans( [0, 6, 0] )
def updateOrientation(): euler = viz.MainView.getEuler() Arrow_Link.setEuler([euler[0], 0, 0]) LookDownCam.setEuler( [euler[0], 90, 0] ) # Heading_UPvizact.ontimer(0, updateOrientation)
手元にスマホライクなマップを表示する_Advanced
This Script Based on using the following equipments. - WorldViz Vizard 7.0 over '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#######################################################################################
import vizimport vizactimport vizshapeimport viztrackerimport vizproximityimport randomimport mathimport csvimport datetimeimport vizinputimport timeimport viztaskimport vizmatimport projectorimport sysimport vizcamimport vizfximport vizconnectimport vizinfo
viz.go()viz.setMultiSample(4)viz.fov(80)
viz.MainView.setPosition([-3.5,1.5,2.5])viz.MainView.setEuler([0,0,0])#viz.MainView.collision(viz.ON)
# Add a white directional light pointing down light = vizfx.addDirectionalLight(euler=(0,90,0), color=viz.WHITE)
###########VIVE###################import steamvr### Setup SteamVR HMD#hmd = steamvr.HMD()#if not hmd.getSensor():# sys.exit('SteamVR HMD not detected')### Setup navigation node and link to main view#navigationNode = viz.addGroup()#viewLink = viz.link(navigationNode, viz.MainView)#viewLink.preMultLinkable(hmd.getSensor())
################################## グローバル変数一覧 #####################################POS_HEAD = [0] #頭位置[x,y,z]POS_HEAD[0] = 0ORI_HEAD = [0] #頭角度[r,p,y]ORI_HEAD[0] = 0
#print POS_HEAD
reset_time = [0] #時刻リセット用変数reset_time[0] = 0
flagLogging = [0] #データ記録フラグflagLogging[0] = False
###############データ出力の準備 #############EVENT_TIMER_ID = 1 #イベントチェックタイマーIDEVENT_TIMER_PERIOD = 0.1 #チェック間隔[s]PROCESS_TIMER_ID = 2 #データ保存タイマーIDPROCESS_TIMER_PERIOD = 0.016666666 #データ保存間隔[s] ≒ 60Hzoutfile = None #出力ファイルオブジェクト(内部用)outcsv = None #CSVフォーマットオブジェクト(内部用)start_time = time.time() #経過時間(内部用)
#subject = 1 #被験者識別番号、実験開始前に被験者毎に設定する##FileName='tanabe_experiment'+datetime.datetime.today().strftime("%Y%m%d")+'_Sub'+str(subject)+'.txt'#Header ='Subject'+'\t'+'Lap_time'+'\t'#Header +='PosX'+'\t'+'PosY'+'\t'+'PosZ'+'\t'+'Yaw'+'\t'+'Pitch'+'\t'+'Roll'+'\n'#expelimental_data = open(FileName,'a') #expelimental_data.write(Header)
################### 左上に検証用サブウィンドウを作成 ####################UpperLeftWindow = viz.addWindow(pos=(0,1.0),size=(0.25,0.25))UpperLeftWindow.visible(0,viz.SCREEN)BirdView = viz.addView() #Create a new viewpointUpperLeftWindow.setView(BirdView) #Attach the bird's eye view to the upper left windowBirdView.setPosition([-2,6,2]) #Move the view above the center of the roomBirdView.setEuler([90,90,90]) #Rotate the view so that it looks downUpperLeftWindow.fov(60)
#MainViewのポジションを赤いConeにリンクさせるview = viz.MainViewCone = vizshape.addCone(radius=0.1,height=0.3, axis=vizshape.AXIS_Z,color = viz.RED)#Cone.renderOnlyToWindows([UpperLeftWindow])viz.link(view,Cone)
################# 軌跡レンダ ################viz.startLayer(viz.LINE_STRIP)viz.vertexColor(viz.YELLOW)lines = viz.endLayer(parent=viz.ORTHO,scene=UpperLeftWindow)
lines.dynamic()
def UpdatePath():
# Get main view position in bird eye window pixel coordinates x,y,z = UpperLeftWindow.worldToScreen(viz.MainView.getPosition(),mode=viz.WINDOW_PIXELS)
# Get position of last line vertex lx,ly,lz = lines.getVertex(-1)
# Add new vertex if current position is different from last position if x != lx or y != ly: lines.addVertex([x,y,0.0])
vizact.ontimer(0,UpdatePath)
#スペースキーで軌跡削除vizact.onkeydown('',lines.clearVertices)
############## Screen and Fix Display ################
## Create render texture for camera video feed#video = viz.addRenderTexture()### Create render node for camera#cam = viz.addRenderNode()#cam.fov = 30.0#cam.setSize(1280,720)#cam.setInheritView(False)#cam.setPosition([-10.0, 11.0, 13.0])#cam.setRenderTexture(video)#cam.setMultiSample(viz.AUTO_COMPUTE)#cam.setRenderLimit(viz.RENDER_LIMIT_FRAME)##def UpdateCamera():# cam.lookAt(viz.MainView.getPosition())#vizact.ontimer(0,UpdateCamera)### Get handle to screen object and apply video feed to it#screen = model.getChild('screen')#screen.texture(video)##Display = vizshape.addPlane(size = [0.4,0.4])#Display.setPosition(0,1,2)#Display.setEuler(0,-40,0)#Display.texture(video)##cam.renderOnlyIfNodeVisible([screen,Display])
################## Following Display ##################### Video as Texturevideo3 = viz.addRenderTexture()
# Camera Settingcam3 = viz.addRenderNode()cam3.fov = 30.0cam3.setSize(2000,2000)cam3.setInheritView(False)cam3.setPosition([-1.9, 8, 2.0])cam3.setEuler([0,90,0])cam3.setRenderTexture(video3)cam3.setMultiSample(viz.AUTO_COMPUTE)cam3.setRenderLimit(viz.RENDER_LIMIT_FRAME)
cam3Link = viz.link( viz.MainView,cam3)cam3Link.setMask(viz.LINK_ORI)cam3Link.preEuler( [0, 90, 0] )
#cam3Link = viz.link( viz.MainView,cam3)#cam3Link.setMask(viz.LINK_POS)#cam3Link.preTrans([0, 8, 0])
# keep Look at the Mainview Movement#def UpdateCamera3():# cam3.lookAt(viz.MainView.getPosition())#vizact.ontimer(0,UpdateCamera3)
# Use up/down keys to zoom camera in/out#def CameraZoom(inc):# cam3.fov = viz.clamp(cam3.fov+inc,5.0,70.0)# cam3.setFov(cam3.fov,1.77,0.1,1000)#vizact.whilekeydown(viz.KEY_UP,CameraZoom,vizact.elapsed(-20.0))#vizact.whilekeydown(viz.KEY_DOWN,CameraZoom,vizact.elapsed(20.0))#CameraZoom(0.0)
#Following Display SettingDisplay_Move = vizshape.addPlane(size = [0.05,0.04])Display_Move.texture(video3)#cam3.renderOnlyIfNodeVisible([Display])
viewLink = viz.link( viz.MainView,Display_Move)viewLink.preTrans( [0.05, -0.04, 0.1] ) viewLink.preEuler( [0, -90, 0] )
################# 地面の生成 ################ground = viz.addChild('ground.osgb')ground.setPosition([0,0,0])
################# 迷路の生成 ################wall1 = vizshape.addBox(size = [4,2,0.05])wall2 = vizshape.addBox(size = [0.05,2,4])wall3 = vizshape.addBox(size = [0.05,2,4])wall4 = vizshape.addBox(size = [4,2,0.05])wall5 = vizshape.addBox(size = [0.05,2,3])wall6 = vizshape.addBox(size = [2,2,0.05])wall7 = vizshape.addBox(size = [0.05,2,2])wall8 = vizshape.addBox(size = [0.05,2,1])wall9 = vizshape.addBox(size = [1,2,0.05])
wall1.setPosition([-2,1,0])wall2.setPosition([0,1,2])wall3.setPosition([-4,1,2])wall4.setPosition([-2,1,4])wall5.setPosition([-1,1,1.5])wall6.setPosition([-2,1,1])wall7.setPosition([-2,1,3])wall8.setPosition([-3,1,2.5])wall9.setPosition([-3.5,1,2])
################# ゴールの生成 ################goal = viz.add('logo.wrl',pos=[-0.5,1.2,0.5],euler=[0,0,0],scale=[0.2,0.2,0.2])
####################################被験者がエリア内にいる時に経路案内のラインを非表示にする######################################################ルートラインを配置##############inport skethupviz.setOption('viz.model.apply_collada_scale',1) route = viz.add('route.dae')#route.renderOnlyToRenderNodes([cam3])route.renderToAllRenderNodesExcept([viz.MainView])route.setPosition([-0.5,0.5,0.5])route.setEuler([90,180,0])
#############センサー追加準備##############Create proximity manager and set debug on. Toggle debug with d keymanager = vizproximity.Manager()manager.setDebug(viz.ON)debugEventHandle = vizact.onkeydown('d',manager.setDebug,viz.TOGGLE)
#Add main viewpoint as proximity targettarget = vizproximity.Target(viz.MainView)manager.addTarget(target)
#############センサーを追加する#############verts = [ [-1,2], [-2,2], [-2,3], [-3,3], [-3,1], [-1,1] ]sensor = vizproximity.Sensor( vizproximity.PolygonArea(verts,offset=[0,0]), None )
#地図を消すdef Enter(e): Display_Move.visible(viz.OFF) #地図を出すdef Exit(e): Display_Move.visible(viz.ON) manager.addSensor(sensor)manager.onEnter(sensor, Enter)manager.onExit(sensor, Exit)
############################### データ出力 ######################################def onTimer(num): # #データを取得し、ファイルへ出力&マスクを移動する# curr_time = time.clock() - reset_time[0]## # POS_HEAD[0] = viz.MainView.getPosition() #頭の位置を取得# ORI_HEAD[0] = viz.MainView.getEuler() #頭の回転角を取得# # data = str(subject)+'\t'+str(round(curr_time,3))+'\t'# data += str(round(POS_HEAD[0][0],3))+'\t'+str(round(POS_HEAD[0][1],3))+'\t'+str(round(POS_HEAD[0][2],3))+'\t'# data += str(round(ORI_HEAD[0][0],3))+'\t'+str(round(ORI_HEAD[0][1],3))+'\t'+str(round(ORI_HEAD[0][2],3))+'\n'# # print data# # expelimental_data.write(data)## prev_time = curr_time##viz.callback(viz.TIMER_EVENT, onTimer)##viz.starttimer(EVENT_TIMER_ID, EVENT_TIMER_PERIOD, viz.PERPETUAL)################################################################################
応用テクニック: 視点の等速移動
スペースキー打鍵中に視点を等速で前進させる(move)
# 初期設定viz.go()ground =viz.addChild('ground.osgb')
# 移動関数MOVE_SPEED = 1.4
def move(): if viz.key.isDown(' '): # スペースキーが押されている場合にのみ移動 viz.MainView.move([0, 0, MOVE_SPEED * viz.elapsed()])# タイマーイベントを設定して定期的にmove関数を呼び出すvizact.ontimer(0, move)
スペースキー打鍵中に視点を等速で前進させる(setPosition)
# 初期設定viz.go()ground =viz.addChild('ground.osgb')
MOVE_SPEED = 1.4
# 移動関数def move(): if viz.key.isDown(' '): # スペースキーが押されている場合にのみ移動 viz.MainView.setPosition([0, 1.5, viz.MainView.getPosition()[2] + (MOVE_SPEED * viz.elapsed())])
# タイマーイベントを設定して定期的にmove関数を呼び出すvizact.ontimer(0, move)
スペースキーを一度打鍵したらずっと等速移動(move)
# Vizardの初期設定viz.go()
# 地面を追加groud = viz.addChild('ground.osgb') # SteamVR HMDの設定hmd = steamvr.HMD()
# HMDの向きと視点の向きをリンクviewLink = viz.link(hmd.getSensor(), viz.MainView)viewLink.setMask(viz.LINK_ORI)
# 等速移動MOVE_SPEED = 1.4def Auto_Move_Forward(): viz.MainView.move([0, 0, MOVE_SPEED * viz.elapsed()], viz.BODY_ORI) # 前進を開始def start_moving(): vizact.ontimer(0, Auto_Move_Forward)
# スペースキーの押下でstart_moving関数を呼び出すvizact.onkeydown(' ', start_moving)
等速移動しながらもHMDの側方への動きは反映(setPosition)
# Vizardの初期設定viz.go()
# 地面を追加groud = viz.addChild('ground.osgb') # SteamVR HMDの設定hmd = steamvr.HMD()
# 等速移動MOVE_SPEED = 1.4def Auto_Move_Forward(): HMD = hmd.getSensor() viz.MainView.setEuler(HMD.getEuler()) viz.MainView.setPosition([ HMD.getPosition()[0], HMD.getPosition()[1], viz.MainView.getPosition()[2] + (MOVE_SPEED * viz.elapsed()) ]) # 前進を開始def start_moving(): vizact.ontimer(0, Auto_Move_Forward)
# スペースキーの押下でstart_moving関数を呼び出すvizact.onkeydown(' ', start_moving)
他のソフトウェアとの連携
各種デバイスとの接続(Vizconnect)
Vizconnect(Vizardに標準装備されている各種デバイスとのコネクトツール)
各種デバイスとの接続状態を記憶したVizconnectファイルを作成
Vizardスクリプト上でVizconnectファイルを読み込んで使用する → VR SOFTWARE WIKI
import vizimport vizconnect
viz.setMultiSample(4)vizconnect.go('config.py')
dojo = viz.addChild('dojo.osgb')
Cyberith Virtualizerとの接続
Cyberith Virtualizer との接続
#### Viz.go ####viz.setMultiSample(8)viz.go()
#### HMD(and Virtualizer/navigation)Setting ###hmd = steamvr.HMD()navigationNode = viz.addGroup()viewLink = viz.link(navigationNode, viz.MainView)viewLink.preMultLinkable(hmd.getSensor())
#### Cyberith Virtualizer Setting ####from cybsdk2 import *
class VirtPlugin: @staticmethod def AngleToVector(angle): return [math.sin(angle), 0, math.cos(angle)] @staticmethod def VectorScale(vector, scale): return [vector[0]*scale, vector[1]*scale, vector[2]*scale]
def updatevirtualizer(self): playerOrientation = virtualizer.GetPlayerOrientation() movementDirection = virtualizer.GetMovementDirection() movementSpeed = virtualizer.GetMovementSpeed()
movement = VirtPlugin.AngleToVector(playerOrientation * 2 * math.pi + movementDirection * math.pi) movement = VirtPlugin.VectorScale(movement, movementSpeed * 1.2) movement = VirtPlugin.VectorScale(movement, viz.elapsed()) navigationNode.setPosition(movement, viz.REL_PARENT) def ResetOrientation(): virtualizer.ResetPlayerOrientation() hmd.getSensor().reset() virtPlugin = VirtPlugin()
# 1. Get devicevirtualizer = Virt.FindDevice()if virtualizer == None: print("No Virtualizer Device Found!")
# 2. Open connectionif virtualizer.Open() == False: print("Unable to connect to Virtualizer!")
# 3. Update every framevizact.onkeydown('r', virtPlugin.ResetOrientation)vizact.ontimer(0, virtPlugin.updatevirtualizer)#######
StarVRとの接続
StarVR ONEとの接続
Display Optimizationの不具合は、先方のサーバの問題かも?
装着後に画面が明滅するときは、締め付けが緩いことがある。
Unityを用いて開発を行う場合、Unity2019のバージョンを使用する。StarVRのUnity統合は、UnityのOpenVRコンポーネントに依存しているが、このコンポーネントはUnity2020から削除されている。Unityのダウングレードはプロジェクトの破損を招くため、最初からUnity2019を使用することがおすすめ。
3dsMaxとの連携
3dsMaxのモデルをvizardに読み込む
3dsMaxでモデルを作成し、書き出し>wrlで名前を付けて保存(例えば ball.wrl)
Vizardで新規vizardファイルを作成し、下記のコードを走らせる。
import viz
viz.go()
ball = viz.add('ball.wrl')
- 3dsMaxでモデルを作成しテクスチャを割り当てる
- レンダラーを「Arnold」に設定する
- 光源を設置してテストレンダリング
- レンダリング > テクスチャベイク > 3Dモデルをクリック > 追加 >
- arnold-rgb > CompleteMapを選択 > 実行
- 出力されたテクスチャファイルをわかりやすい場所に保存
- 3dsMaxの球体モデルを、書き出し>wrlで保存(cf.ball.wrl)
- 保存したwrlファイルをVizard inspecterで開く(右クリック>プログラム>inspecter)
- ウィンドウ右側のmaterialの「+」ボタンを開き、 テクスチャファイルをドロップ
- 名前をつけて保存(例えばball.osgb, 自動的にosgb形式で保存される)
- 同一階層で新規vizardファイルを作成し、下記のコードを走らせる。
import viz
viz.go()
ball = viz.add('ball.osgb')
3dsMax2024でのテクスチャベイク
3dsMAXで、1m四方の立方体を作成して
テクスチャベイクしてFBXで出力する手順
0. 3ds Maxの起動
3ds Maxを起動し、新しいシーンを作成
1. 立方体の作成
右側のコマンドパネルの「作成」タブを選択
標準プリミティブ>ボックス>
ビューポートでドラッグして立方体を作成
パラメータロールアウトで一辺を1mに設定
2. マテリアルの設定
メインツールバーのマテリアルエディタを長押し
スレート マテリアル エディタを選択して開く
右ブラウザからフィジカルマテリアルを選択し挿入
ビットマップに画像を設定し、ベースカラーに連結
3. UVマッピングの設定
立方体を選択し、右側のコマンドパネル>修正タブ
モディファイヤリスト>UVWマップを選択して適用
ボックスなどを選び、テクスチャのラップ方法を指定
4. 照明の追加
作成タブ>ライト>ターゲットライト
ビューポートをクリックし光源を追加
アンビエントとして二つ目の光源を追加
レンダリングを実行し配置や輝度を調整
5. テクスチャラップの設定
ツールバー>レンダリング>テクスチャレンダリング
アンラップのみを実行し、自動フラッテンUVを生成
修正タブ>自動フラッテンUVを選択
UVエディタを開いて、クイックピールを実行
自動フラッテンUV>チャネル>UVW設定の保存
6. テクスチャベイク
立方体を選択し、「テクスチャレンダリング」を選択
立方体を選択した状態で、出力>追加>CompleteMap
マップサイズは大きめに設定しレンダリング
立方体を選択し、「テクスチャにベイク処理」を選択
Arnold>complete>+選択したオブジェクトにマップを追加
ベイク処理を実行して、ベイクテクスチャを出力
7. ベイク後のマテリアル適用
モディファイヤリストで「UVWアンラップ」を選択
チャネル>ロード>6で保存したUVW設定を読み込む
マテリアルエディタ>フィジカルマテリアル>
ベイクしたテクスチャをビットマップとしてベースカラーに連結
作成したマテリアルを立方体(UVWアンラップ)に適用
8. FBX形式での出力
ファイル>書き出し(or 選択を書き出し)を選択
ファイル形式を「FBX」としてエクスポート
設定ダイアログで「ライト」のチェックを外すとよい
9.出力結果の確認
Vizard Inspecterなどでfbxファイルを開き、状況を確認
How to Create a VR Experiment with Vizard
Performing Eye Tracking Studies in VR
Mixiamoとの連携
import vizimport vizactimport vizfx
viz.go()viz.fov(90)ground = viz.addChild('ground.osgb')
viz.MainView.setPosition(0,1.5,-5)
avatar = vizfx.addAvatar('PinkMan.osgb',pos =(-3,0,0),euler =[90,0,0])avatar.state(1)
def avatarTurn(): deg = avatar.getEuler() turn =vizact.turn(deg[0]+180,180,anim=1) avatar.runAction(turn)vizact.onkeydown('0',avatarTurn)
def avatarWalk(): walk = vizact.walkTo([3,0,0],1.5, walkAnim=2) avatar.runAction(walk)vizact.onkeydown('1',avatarWalk)
def avatarRun(): run = vizact.walkTo([-3,0,0],3.0, walkAnim=3) avatar.runAction(run)vizact.onkeydown('2',avatarRun)
def avatarSlowWalk(): SlowWalk = vizact.walkTo([3,0,0],1.1, walkAnim=4) avatar.runAction(SlowWalk)vizact.onkeydown('3',avatarSlowWalk)
Mixamo to Vizard 手順
- Mixiamoでキャラクターを選択しfbxで保存 → Link
- キャラクターをvizard inspecterで開き各種調整
- OSGB形式で保存
- Vizardに読み込む( A = vizfx.addAvatar(***.osgb))
キャラクターのスケール調整
- SceneGraphのツリー上層に”Transform”のnodeを追加する
- 追加したTransformのnodeに対して拡大縮小を割り当てる
アニメーションの追加
- Mixiamoから”WithoutSkin”でアニメーションデータをDL
- 移動系のアニメーションはinPlaceを指定してDLがよい
- inspecter右のAnimeationにimportすればState化される
viz.go()piazza = viz.addChild('piazza.osgb')
########### SteamVR HMDの設定 #############import steamvrhmd = steamvr.HMD()viz.link(hmd.getSensor(), viz.MainView)
############### コントローラー操作 ###############
Controller1 = steamvr.getControllerList()[0]Controller2 = steamvr.getControllerList()[1]
def ControllerState():
Trig_State_1 = Controller1.getTrigger()Pad_State_1 = Controller1.getTrackpad()
Trig_State_2 = Controller2.getTrigger()Pad_State_2 = Controller2.getTrackpad() data = str(Trig_State_1)+','+str(Pad_State_1)+','+str(Trig_State_2)+','+str(Pad_State_2)+'\n'
print(data)
vizact.ontimer(0,ControllerState)