Vizard
Requirements
To follow the first part of the tutorial only requirement is to have the Vizard installed (link to Vizard installation instruction).
The second part of the tutorial involves running the simple world you created in VR, which requires having a HMD headset and controllers. The tutorial was tested with a HTC VIVE, but should also work with an Oculus Rift without any change in the instructions.
Tutorial
Final Result
After completing this tutorial you are going to have something similar to this working in VR.
First config file
Open Vizard. First we are going to use the tool Vizconnect to generate for us a configuration file which provides a easy way to define the user interaction inside of the virtual world.
To start Vizconnect click "tools>vizconnect"
This will automatically propt you to create a file, which you should name "config.py".
Vizconnect interface will open and prompt you to select how you will create the configuration file.
Choose "select from some common present configurations" and pick the first default configuration.
We are going to start building our World using the default configuration (which do not require any VR setup) and then later on we will change this configuration file to work with the HTC VIVE.
Notice that when you run the config.py file in the Vizard interface 2 things happen: the vizconnect interface starts up and a simple world also is loaded.
You can interact with this simple 3D environment using your mouse and keyboard (as is specified in the config file). The point of this 3d environment is that the changes that you make in the vizconnect configurations are reflected right away in this simulation, which means that you can easily check that you are setting up your configuration file correctly.
Our first world
Now we are going to briefly ignore the configuration file and we are going to simply these default configurations while we create a simple 3D world. Create a new file called world.py. In this file we are going to set up our 3d environment. In order to with the environment using the configuration that we wrote to the config.py file use the following lines of code:
import viz
import vizconnect
import vizshape
import vizact
viz.setMultiSample(4)
vizconnect.go('config.py')
viz.phys.enable()
# Add a background environment
dojo = viz.addChild('dojo.osgb')
Try to run world.py and move around using the mouse and keyboard.
Now we are going to add some objects to the room. Adding the following code will create a box and 7 balls. (feel free to add different object and experiment with the various settings)
box = viz.addChild('crate.osgb')
box.setPosition([0,0.5,3])
box.setScale([1,1,7])
box.alpha(1)
balls= []
for x in range(7):
ball = viz.addChild('beachball.osgb',cache=viz.CACHE_COPY)
ball.setScale([0.5,0.5,0.5])
ball.alpha(1)
ball.setPosition([0,3,x])
balls.append(ball)
If you run the world.py now you will notice that the balls are sospended mid air. The reason that this happens is that they are not objects part of the phisic simulation. in order to make the ball and the box phisical object change to code to be similar to the following.
import viz
import vizconnect
import vizshape
import vizact
viz.setMultiSample(4)
vizconnect.go('config.py')
viz.phys.enable()
# Add a background environment
dojo = viz.addChild('dojo.osgb')
box = viz.addChild('crate.osgb')
box.setPosition([0,0.5,3])
box.setScale([1,1,7])
box.collideMesh()
box.alpha(1)
balls= []
for x in range(7):
ball = viz.addChild('beachball.osgb',cache=viz.CACHE_COPY)
ball.setScale([0.5,0.5,0.5])
ball.collideSphere(bounce = 1, friction = 1, hardness= 1, density = 1)
ball.alpha(1)
ball.setPosition([0,3,x])
balls.append(ball)
Now you should test that the phisics work. You can do this for example by making the ball all appear very close to each other. The balls should already be able to collide with each other, with the box, and with the rest of the environment (walls, columns, etc, etc)
Grabbing and other fun stuff
Now that we have created balls and that they can phisically interact with the environment. We are going to use the "tool" feature of Vizconnect to easily be able to grab objects in the 3d world. In order to set up a grabber, go back to the config.py and run it. Once the advance vizconnect interface has loaded you should be able to see a tab called tools.
Create a new Grabber tool (make sure to enable physics)
Once the grabber is created you need to make sure that in the scene graph side bar it is set as a child of the right hand. The you can go back to the tool tab and click on the grabber's mappings button. This will allow you to decide which of the controllers will toggle grabbing. The following picture shows how to set up the grabber so that objects will be picked up by holding the mouse left button.
After you are done with this exit from the viz connect window and from the 3d simulation window. Vizard will let you know that the configuration file has been modified. Accept these changes.
Before we can actually see what the grabber can do, we need to make a couple of modification to the world.py file. Essentially we have to tell the grabber what objects it is allowed to interact with.
In order to do this add the following code at the end of world.py (you can change this code to reflect the objects that you want the grabber to interact with):
grabber = vizconnect.getRawTool('grabber')
grabber.setItems(balls)
Now try to run world.py and try to play with the balls. You should be able to use your hand to pick them up.
Before you move on to the VR section of the tutorial I suggest you try to make your virtual world a little be more exciting. Here are some ways you can do that:
It is possible to create events hadlers for events such as picking up/colliding with it or relesing an object. The following code for example allows you to increase the speed at which you throw balls.
from tools import grabber
def onRelease(e):
e.released.setVelocity([x * 1.5 for x in e.released.getVelocity()])
viz.callback(grabber.RELEASE_EVENT, onRelease)
Similarly this code (which comes from one of the vizard tutorials I believe) will make the object that is grabbed grow and shrink while you hold on to it
scaleAction = vizact.sequence([vizact.sizeTo(size=[1.3,1.3,1.3],time=1),vizact.sizeTo(size=[1,1,1],time=1)], viz.FOREVER)
def onGrab(e):
e.grabbed.runAction(scaleAction,pool=1)
def onRelease(e):
e.released.endAction(pool=1)
from tools import grabber
viz.callback(grabber.GRAB_EVENT, onGrab)
viz.callback(grabber.RELEASE_EVENT, onRelease)
Another useful feature that you may want to explore are timers. The following code for example sets up a times that goes of every ten seconds and resets the position of all the balls.
RESET_TIMER = 1
def timerCallback(num):
#Use the time ids to identify the timer.
if num == RESET_TIMER:
for x in range(7):
balls[x].setPosition([0,3,x])
viz.callback(viz.TIMER_EVENT, timerCallback)
viz.starttimer( RESET_TIMER, 10, viz.PERPETUAL )
VR Setup
Now that you have created a relatively active world, you are going to want to visit it in VR. So go back to visconnect and set up the config file to work with the VIVE (or oculus). From now on it is suggested to follow the tutorial from a computer that has a VR device connected (Headset + controllers). Otherwise you will have no way to know if the configuration you are making are working or not.
I am going to assume that the current tutorial is done with a VIVE, but the same instruction can be followed with minor changes using a different device.
Steps:
run the config.py again to start up vizconnect
Lets first remove the old trackers and add new trackers. In order to remove the old trackers (keyboard and mouse), go to the tracker tab select the existing trackers and click on remove selected. Now add 3 new trackers: one for the headset and 2 for the controller. To do this click on "Add new tracker" and then select the approriate device type (steam VR controller and Steam VR HMD tracker shoud work).
Second, change the avatar: go to the avatar tab. Remove the old avatar. Add a the head_and_hand avatar. NOTE: Make sure that you add a file to diplay for both the right and left hand.
Now we need to connect our avatar head and hands to the new trackers. To do this you need to go in the avatar tab and click on the animator botton. Then for the head and the 2 hands, you need to select the trackers that we just added. After you do this and you click on apply, you should already see that the 3d environment's view is now following the HMD position.
Right now despite the fact that the main view is aligned with the VIVE you still are not using the vive as your primary monitor (which means that nothing is displayed in stereo). In order to set the headset as the primary diplay device go to the diplay tab, remove the old display and add the VIVE as a new diplay. Then drag the new main_diplay in the "Scene Graph" side bar to be a child of the head.
Add the VIVE controllers as 2 new input methods. This can be done in the input tab. (feel free to remove previous input methods). In order to select both controllers change the index field of the second controller to 1 (This should ensure that you are not selecting the same controller twice).
Now that you have these new input methods, you are going to set up a new way to move. In order to do this go to the transport tab. There change the mappings of the main_transport to map to one of the botton on the controllers we added. In order to get the correct behavious for the foward movement (it brings you forward with respect to the view and not with respect to global coordinates) hit on the setting botton of the main_transport and select the headset as a the orientation device.
The last important thing that you need to fix are the grabber configuration. The configuration we had before relied on mouse input. Now we want to use the input from the controllers. In order to do this we can go to the tool tab, click on mappings for the grabber, and assign a new mapping to the grab_and_release behaviour.
Optional but kind of cool: add a few hand gestures to your digital hands. This can be done in the Avatar tab under the hand gesture botton.For example, you may want the digital hand to close when the button that we selected for the grabber is toggled.
DONE!
Now if you run world.py with these new configuration , you should be able to interact with your virtual environment only using the headset and the controllers. To make it even more fun add other tools (The pencil tool is a must try).