Difference between revisions of "VRET Vizard"
(31 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
== Getting Started == | == Getting Started == | ||
Vizard has a very nice tutorial and help file that is also available online on the [http://www.worldviz.com/vizhelp/VizHelp.htm Vizard] website. It explains the basics of Vizard and also if needed the basics of [http://www.python.org/ Python] the language used to control Vizard. | Vizard has a very nice tutorial and help file that is also available online on the [http://www.worldviz.com/vizhelp/VizHelp.htm Vizard] website. It explains the basics of Vizard and also if needed the basics of [http://www.python.org/ Python] the language used to control Vizard. | ||
+ | |||
+ | === Character pack === | ||
+ | CFG files are actually plain text files that gather up the names and locations of all the various parts of the avatars: CSF (skeleton), CAF (animations), CMF (meshes), CRF (materials). They can be opened in any plain text editor, such as notepad. I am not aware of any plugins that allow cal3d files to be imported into modeling programs such as 3ds max. ([http://forum.worldviz.com/showthread.php?t=1631&highlight=modeling+software source]) | ||
+ | |||
+ | ==== Cal3D ==== | ||
+ | The file format for Vizard characters (.CFG). | ||
+ | |||
+ | Vizard uses a somewhat older version of cal3d that has been slightly modified, so it is probably incompatible with the versions available on the cal3d website. ([http://forum.worldviz.com/showthread.php?t=1659&highlight=maya source]) | ||
+ | So get the plugin from the [http://www.worldviz.com/download/index.php?id=9 Vizard site] | ||
+ | |||
+ | ==== Animation files and 3DS Max ==== | ||
+ | A small and quick tutorial (originally for the course IUXE) on how to import animation files into 3DS Max and export the model and its animations for use with Vizard. | ||
+ | [http://www.bladegash.net/files/CustomAvatarsforVizard.doc Click] (u/p: vret_oud/vret_oud) | ||
+ | |||
+ | The end result is the following, basic looking, avatar: [http://www.bladegash.net/files/IUXE_avatar.zip Click] (u/p: vret_oud/vret_oud) | ||
+ | |||
+ | == Resources == | ||
+ | Vizard comes with a few build in object like avatars and a duck but you most likely want to add your own objects too your program. To avoid having to use absolute paths you can add your directory to the path list of Vizard so that you can reffere to the object directly. | ||
+ | |||
+ | :viz.res.addPath(<'directory') example: viz.res.addPath('G:\Vizard projects') | ||
+ | |||
+ | you can also reffere to the directory where the main (running) .py file is located by adding the line | ||
+ | |||
+ | :viz.res.addPath('\\\\') | ||
+ | |||
+ | You can also reffere to objects in subdirectory's of the path directory's you added. example: | ||
+ | |||
+ | :viz.add('Avatars\Male\casual09_m_highpoly.cfg') | ||
== HMD == | == HMD == | ||
Line 11: | Line 39: | ||
=== flockofbirds === | === flockofbirds === | ||
+ | [[flockofbirdsdetailed|Detailed documentation]] | ||
+ | |||
+ | ==== Adding flock of birds sensor ==== | ||
+ | ascension = viz.add('ascension.dle') | ||
+ | |||
+ | bird = ascension.addFlockOfBirds(birds=1, port=0, hemisphere=ascension.HEMI_FRONT )[0] | ||
+ | |||
+ | link = viz.link(bird, viz.MainView) # Link the tracker to the main view | ||
+ | |||
+ | ==== Resetting view to right position ==== | ||
+ | def resetLink(): | ||
+ | :link.reset(viz.RESET_OPERATORS) | ||
+ | |||
+ | :euler_offset = [123.09078979492187, 5.588435173034668, -95.282585144042969] # enter your offset here | ||
+ | |||
+ | :inv_quat = viz.Matrix.euler(euler_offset).inverse().getQuat() | ||
+ | |||
+ | :link.preQuat(inv_quat,target=viz.LINK_ORI_OP) | ||
+ | |||
+ | :hmd_yaw = link.getEuler()[0] | ||
+ | |||
+ | :link.postEuler([-hmd_yaw,0,0]) | ||
+ | |||
+ | vizact.onkeydown('r',resetLink) | ||
=== emagin === | === emagin === | ||
Line 19: | Line 71: | ||
'''Don't forget to disable the eMagin mouse drivers if these are enabled in the "Control Panel>System>Hardware>Device Manager" list''' | '''Don't forget to disable the eMagin mouse drivers if these are enabled in the "Control Panel>System>Hardware>Device Manager" list''' | ||
+ | |||
+ | '''Also make sure that the utility program of eMagin isn't running because only one program is allowed to access the tracker''' | ||
+ | |||
+ | == Support == | ||
+ | We got a year payed Vizard support that can be used when you run into problems. There is a public Vizard [http://www.worldviz.com/forum/search.php?s= forum] where you can post your problems but if you ain't getting the required answer there a ticket can be opened on the closed Vizard [http://support.worldviz.com support] section. The ticket has to be opened by [[User:Wouter|Wouter Pasman]] but after that can be replied by and seen by anyone having the correct url. | ||
+ | |||
+ | |||
+ | == Overriding Mouse Navigation in Vizard == | ||
+ | |||
+ | Vizard comes standard with a rather annoying mouseclick navigation. | ||
+ | The following class extends the FlyNavigate.py class: | ||
+ | |||
+ | <code lang=python> | ||
+ | import viz | ||
+ | import vizcam | ||
+ | |||
+ | class WorldNavigator(vizcam.FlyNavigate): | ||
+ | |||
+ | MOUSE_LEFT_DOWN = False | ||
+ | |||
+ | def __init__(self): | ||
+ | # Default movement keys | ||
+ | vizcam.FlyNavigate.__init__(self,'w','s','a','d') | ||
+ | |||
+ | # Only update the mouse movement if the left mouse has been clicked | ||
+ | def _camMouseMove(self,e): | ||
+ | if self.MOUSE_LEFT_DOWN == True: | ||
+ | vizcam.FlyNavigate._camMouseMove(self,e) | ||
+ | |||
+ | def _camMouseDown(self,e): | ||
+ | if e.button == viz.MOUSEBUTTON_LEFT: | ||
+ | self.MOUSE_LEFT_DOWN = True | ||
+ | |||
+ | def _camMouseUp(self,e): | ||
+ | self.MOUSE_LEFT_DOWN = False | ||
+ | |||
+ | # Overidden to add a bit of logic | ||
+ | def _camUpdate(self,e): | ||
+ | vizcam.FlyNavigate._camUpdate(self,e) | ||
+ | |||
+ | mousePos = viz.mouse.getPosition(viz.WINDOW_PIXELS, True) | ||
+ | windowSize = viz.window.getSize() | ||
+ | |||
+ | # If the mouse cursor leaves the client window then | ||
+ | # don't bother updating the _camMouseMove parent function | ||
+ | if mousePos[0] <= 0: | ||
+ | self.MOUSE_LEFT_DOWN = False | ||
+ | elif mousePos[0] >= windowSize[0]: | ||
+ | self.MOUSE_LEFT_DOWN = False | ||
+ | elif mousePos[1] <= 0: | ||
+ | self.MOUSE_LEFT_DOWN = False | ||
+ | elif mousePos[1] >= windowSize[1]: | ||
+ | self.MOUSE_LEFT_DOWN = False | ||
+ | |||
+ | |||
+ | |||
+ | Then, to apply this new navigation, add the following line in the program: | ||
+ | |||
+ | viz.cam.setHandler(WorldNavigator()) | ||
+ | </code> | ||
+ | |||
+ | == Connecting the GOAL IDE with Vizard == | ||
+ | |||
+ | In order to connect GOAl with Vizard, take the following steps. | ||
+ | |||
+ | Download the file [[Media:XMLRPCServer.zip]] , extract it and add/import it to the workspace of Vizard/Eclipse. | ||
+ | |||
+ | Add the following functions to your vizard program: | ||
+ | |||
+ | def initGOALconnection(self): | ||
+ | self.XMLserver = XMLRPCServer.XMLRPCServer("vizardserver", ("ip-address",8000)) | ||
+ | print "Listening on port 8000..." | ||
+ | self.XMLserver.register_function(self.vizact, "vizact") | ||
+ | self.XMLserver.register_function(self.getPercept, "getPercept") | ||
+ | print "connection made!" | ||
+ | |||
+ | *NB : the "ip-address" should be replaced by the ip address of your machine. | ||
+ | |||
+ | def vizact(self, entity): | ||
+ | pass | ||
+ | // do your thing here. vizact is the actions that GOAL sends to you. Don't forget to parse the strings correctly! | ||
+ | |||
+ | def getPercept(self, entity): | ||
+ | return -1 | ||
+ | // This function should return a percept of the chosen entity in string format. | ||
+ | // for example : return "position(1,1,1)" | ||
+ | // return "state(hungry)" | ||
+ | // be aware of ints/floats inside the string. For GOAL (prolog) 1 and 1.0 are different. | ||
+ | |||
+ | Now register a check function to allow Vizard to handle 1 request of the XMLServer each XX seconds | ||
+ | vizact.ontimer(0.1,self.checkGOAL) | ||
+ | |||
+ | def checkGOAL(self,event): | ||
+ | self.XMLserver.serve_once() | ||
+ | |||
+ | == Avatar Loader == | ||
+ | Works on computer Zijl but can be edited to work on all systems just change the RESOURCEURL variable in the class file. | ||
+ | |||
+ | [http://mmi.tudelft.nl/vret_oud/images/0/01/CharacterLoader.zip AvatarLoader Download] | ||
+ | |||
+ | for avatar numbers check the avatar picture [[VRET_Avatars|overview]] | ||
+ | |||
+ | === Example === | ||
+ | ch = CharacterLoader('Avatars') #Avatars is the directory to store the Avatar files in | ||
+ | |||
+ | avatar = viz.add('Avatars\\'+ch.getAvatar(ch.MALE,ch.CHILD,ch.NONE,'02',ch.MEDIUMPOLY)) | ||
+ | |||
+ | #getAvatar(gender,age,type,number,polyCount) type = CASUAL, BUSINESS, NONE not every age has a type | ||
+ | |||
+ | == Tips == | ||
+ | |||
+ | === Vizard and Threading === | ||
+ | viz.directormode(viz.DIRECTOR_FAST) | ||
+ | |||
+ | This tells Vizard to allow Python threads to run while Vizard is drawing. Technically speaking, this will instruct Vizard to relase the GIL while rendering. For more information about the GIL and how Python threads behave, have a look at this page, http://docs.python.org/api/threads.html |
Latest revision as of 14:57, 9 February 2010
Contents
Getting Started
Vizard has a very nice tutorial and help file that is also available online on the Vizard website. It explains the basics of Vizard and also if needed the basics of Python the language used to control Vizard.
Character pack
CFG files are actually plain text files that gather up the names and locations of all the various parts of the avatars: CSF (skeleton), CAF (animations), CMF (meshes), CRF (materials). They can be opened in any plain text editor, such as notepad. I am not aware of any plugins that allow cal3d files to be imported into modeling programs such as 3ds max. (source)
Cal3D
The file format for Vizard characters (.CFG).
Vizard uses a somewhat older version of cal3d that has been slightly modified, so it is probably incompatible with the versions available on the cal3d website. (source) So get the plugin from the Vizard site
Animation files and 3DS Max
A small and quick tutorial (originally for the course IUXE) on how to import animation files into 3DS Max and export the model and its animations for use with Vizard. Click (u/p: vret_oud/vret_oud)
The end result is the following, basic looking, avatar: Click (u/p: vret_oud/vret_oud)
Resources
Vizard comes with a few build in object like avatars and a duck but you most likely want to add your own objects too your program. To avoid having to use absolute paths you can add your directory to the path list of Vizard so that you can reffere to the object directly.
- viz.res.addPath(<'directory') example: viz.res.addPath('G:\Vizard projects')
you can also reffere to the directory where the main (running) .py file is located by adding the line
- viz.res.addPath('\\\\')
You can also reffere to objects in subdirectory's of the path directory's you added. example:
- viz.add('Avatars\Male\casual09_m_highpoly.cfg')
HMD
With just a few lines of code Vizard can easily work with an HMD. All you need to add/replace from your code to get a image on the HMD are:
- viz.displaymode(800,600,32,60) <viz.displaymode(width-screen,heigh-screen,color depth,refresh rate)>
- viz.go(viz.QUAD_BUFFER |viz.FULLSCREEN) <replace the viz.go() with this>
Trackers
flockofbirds
Adding flock of birds sensor
ascension = viz.add('ascension.dle')
bird = ascension.addFlockOfBirds(birds=1, port=0, hemisphere=ascension.HEMI_FRONT )[0]
link = viz.link(bird, viz.MainView) # Link the tracker to the main view
Resetting view to right position
def resetLink():
- link.reset(viz.RESET_OPERATORS)
- euler_offset = [123.09078979492187, 5.588435173034668, -95.282585144042969] # enter your offset here
- inv_quat = viz.Matrix.euler(euler_offset).inverse().getQuat()
- link.preQuat(inv_quat,target=viz.LINK_ORI_OP)
- hmd_yaw = link.getEuler()[0]
- link.postEuler([-hmd_yaw,0,0])
vizact.onkeydown('r',resetLink)
emagin
To get Vizard to accept input from the eMagin tracker (integrated in the HMD) you need to add the tracker as a sensor in Vizard and then link the sensor to the mainView-point
- sensor = viztracker.add('emagin.dls')
- viz.link(sensor,viz.MainView)
Don't forget to disable the eMagin mouse drivers if these are enabled in the "Control Panel>System>Hardware>Device Manager" list
Also make sure that the utility program of eMagin isn't running because only one program is allowed to access the tracker
Support
We got a year payed Vizard support that can be used when you run into problems. There is a public Vizard forum where you can post your problems but if you ain't getting the required answer there a ticket can be opened on the closed Vizard support section. The ticket has to be opened by Wouter Pasman but after that can be replied by and seen by anyone having the correct url.
Vizard comes standard with a rather annoying mouseclick navigation. The following class extends the FlyNavigate.py class:
import viz
import vizcam
class WorldNavigator(vizcam.FlyNavigate):
MOUSE_LEFT_DOWN = False
def __init__(self):
# Default movement keys
vizcam.FlyNavigate.__init__(self,'w','s','a','d')
# Only update the mouse movement if the left mouse has been clicked
def _camMouseMove(self,e):
if self.MOUSE_LEFT_DOWN == True:
vizcam.FlyNavigate._camMouseMove(self,e)
def _camMouseDown(self,e):
if e.button == viz.MOUSEBUTTON_LEFT:
self.MOUSE_LEFT_DOWN = True
def _camMouseUp(self,e):
self.MOUSE_LEFT_DOWN = False
# Overidden to add a bit of logic
def _camUpdate(self,e):
vizcam.FlyNavigate._camUpdate(self,e)
mousePos = viz.mouse.getPosition(viz.WINDOW_PIXELS, True)
windowSize = viz.window.getSize()
# If the mouse cursor leaves the client window then
# don't bother updating the _camMouseMove parent function
if mousePos[0] <= 0:
self.MOUSE_LEFT_DOWN = False
elif mousePos[0] >= windowSize[0]:
self.MOUSE_LEFT_DOWN = False
elif mousePos[1] <= 0:
self.MOUSE_LEFT_DOWN = False
elif mousePos[1] >= windowSize[1]:
self.MOUSE_LEFT_DOWN = False
Then, to apply this new navigation, add the following line in the program:
viz.cam.setHandler(WorldNavigator())
Connecting the GOAL IDE with Vizard
In order to connect GOAl with Vizard, take the following steps.
Download the file Media:XMLRPCServer.zip , extract it and add/import it to the workspace of Vizard/Eclipse.
Add the following functions to your vizard program:
def initGOALconnection(self): self.XMLserver = XMLRPCServer.XMLRPCServer("vizardserver", ("ip-address",8000)) print "Listening on port 8000..." self.XMLserver.register_function(self.vizact, "vizact") self.XMLserver.register_function(self.getPercept, "getPercept") print "connection made!"
- NB : the "ip-address" should be replaced by the ip address of your machine.
def vizact(self, entity): pass // do your thing here. vizact is the actions that GOAL sends to you. Don't forget to parse the strings correctly!
def getPercept(self, entity): return -1 // This function should return a percept of the chosen entity in string format. // for example : return "position(1,1,1)" // return "state(hungry)" // be aware of ints/floats inside the string. For GOAL (prolog) 1 and 1.0 are different.
Now register a check function to allow Vizard to handle 1 request of the XMLServer each XX seconds
vizact.ontimer(0.1,self.checkGOAL)
def checkGOAL(self,event): self.XMLserver.serve_once()
Avatar Loader
Works on computer Zijl but can be edited to work on all systems just change the RESOURCEURL variable in the class file.
for avatar numbers check the avatar picture overview
Example
ch = CharacterLoader('Avatars') #Avatars is the directory to store the Avatar files in
avatar = viz.add('Avatars\\'+ch.getAvatar(ch.MALE,ch.CHILD,ch.NONE,'02',ch.MEDIUMPOLY))
- getAvatar(gender,age,type,number,polyCount) type = CASUAL, BUSINESS, NONE not every age has a type
Tips
Vizard and Threading
viz.directormode(viz.DIRECTOR_FAST)
This tells Vizard to allow Python threads to run while Vizard is drawing. Technically speaking, this will instruct Vizard to relase the GIL while rendering. For more information about the GIL and how Python threads behave, have a look at this page, http://docs.python.org/api/threads.html