PDA

View Full Version : Weird lagging/choppiness when avatars perform actions


vjonshih
11-24-2004, 05:25 PM
Hi there,

I have a world where 7 avatars (actually, agents) are visible all at once and are timed to perform certain actions (like raising their hands, nodding, shaking their heads, etc.)

However, I've noticed that whenever any one of them are called to do their actions, the screen lags or jumps a bit -- which is extremely noticeable when you are viewing the world from an HMD headset. In other words, the frame rate is smooth (60 fps) when no actions are being performed by the avatars on the screen...so we know that the polygon count is not an issue...however, the frame rate becomes temporarily choppy (~33 fps) when one or more of the avatars perform an action/animation.

Do you know how to fix this weird jump/lag problem?

Thanks,
Jon

farshizzo
11-24-2004, 05:44 PM
Hi,

Does the lag occur every time an avatar performs an action? Does the lag last as long as the action? Can you try running the following script and seeing if it reproduces the lag. The script loads 7 avatars and pressing the spacebar will execute an animation on one of them. I've tried it here and I don't notice a lag.import viz
viz.go()

NUM_AGENTS = 7

for x in range(NUM_AGENTS):
agent = viz.add('male.cfg')
agent.translate((NUM_AGENTS/-2.0) + x*1.5,0,15)
agent.rotate(180,0,0)
agent.state(1)

def onkeydown(key):
if key == ' ':
agent.execute(5)

viz.callback(viz.KEYDOWN_EVENT,onkeydown)

vjonshih
11-28-2004, 05:40 PM
Hi,

I tried your script and everything ran smoothly...

But I think my problem is a little more complicated -- the thing is, I have 7 timers running at once (so that each avatar performs a given action every x seconds, according to his own timer) -- so there are times when actions are performed by multiple avatars almost simultaneously. It just seems as if whenever the program is about to call an action to be performed, the tracking lags and the result is a feeling of "jumping" from one part of the screen to another (while you're moving your head within the HMD)

I'm not sure how else to describe it...

farshizzo
11-29-2004, 12:03 PM
Hi,

Are you performing any extensive calculations in your timers? It seems as though the lag is coming from one of your timers. Try commenting out pieces of code in your timer until the lag goes away. This way you can locate the source of the lag.

vjonshih
11-30-2004, 04:16 PM
So there are two complex "actions" in the code that we've found to possibly have been affecting the lag...I want to know if you have any suggestions as to any possible (relatively easy) solutions:

(1) We have whole-body animations exported from Character Studio Max (.cax) files...whenever the timers call a .cax animation, *no* lag occurs. However, we also have these complex recorded-head-movement animations. What we've done is record head-movements into text files, and then at the beginning of the script, we read all of the data into an array -- and when we call for an avatar to perform that specific head movement, we have a timer call to run through index 1000 through 10000 (for instance) of the action array and make the avatar's head move according to the pitch,yaw,roll data in the array. This seems to be stalling the computer a bit -- we don't read in the specific text file containing the head movement data EACH time we call the avatar to perform that action, so that's not an issue. However, it must be the fact that when multiple avatars are doing different recorded head movements, all of the timer calls to the centralized head-movement-data array stalls the computer.

Do you know of any way to export/import text files containing lines of head-movement-data into a program like Character Studio Max and then re-exporting it out to a .cax file or something of that sort? If so, that would solve that particular lag problem I think.

(2) When we commented out the timers that called the head-movement actions to be performed, the lag was still there but it was less prominent. We've narrowed it down to the action of making the avatars speak a .wav file. There are about 8 or so .wav files for each of the 7 avatars that we have them speak -- but we don't have them preloaded into the script before hand (via sound = viz.add('speech.wav')) -- so, apparently, each time the timer calls for a specific avatar to speak a certain .wav file, Vizard is opening up that .wav file each time to run. Is it better/possible to load all the .wav files beforehand in the script via viz.add -- and then have the timers call them to be spoken later on?

Sorry for the verbosity of this message...but I really appreciate any suggestions you have to offer!

farshizzo
11-30-2004, 04:35 PM
Hi,

(1) What you are doing here seems fine. Are you simply taking a value from the array and applying it to the head rotation? Or, are you doing some calculation with the data each frame? Also, make sure that you are not generating any extra timers. A common problem is starting multiple timers within a timer callback. If this is the case, then the number of timers in your script will be exponentially increasing.

(2) This will definitely cause a lag. Speech actions are only meant to be generated at initialization. Once you generate a speech action, you can reuse it multiple times and on multiple avatars.avatar1 = viz.add('male.cfg')
avatar2 = viz.add('male.cfg')
avatar3 = viz.add('male.cfg')

#Generate a speech action
speech = avatar1.speak('speech.wav')

#Make all 3 avatars speak
avatar1.act(speech)
avatar2.act(speech)
avatar3.act(speech)This will work with all action types, not just speak actions

vjonshih
11-30-2004, 04:44 PM
You rock, Farshid.

Thanks for your help.

After much commenting out/commenting in, etc. -- we've figured out the MAIN cause of the lag -- something we didn't expect.

So it turns out that we have these emotion faces that we texture onto the heads of the avatars on demand. The code in the person class for the "changehead" method looks like this:

def changehead(self, emotion):
texture = self.prefix + '_Bio_UV_Head' + emotion + '.jpg'
newtexture = viz.add(texture)
newtexture.wrap(viz.WRAP_S,viz.REPEAT)
newtexture.wrap(viz.WRAP_T,viz.REPEAT)
self.head.texture(newtexture, 'geom_0')

The timers have nothing to do with this lag -- if I designate a key to replace the head texture of any given avatar -- and press a bunch of the keys at once to change multiple heads...the Frame Rate goes from 60fps to 30fps to 10fps...it slows down DRAMATICALLY. Do you know any way to get around this? Or what's causing this?

farshizzo
11-30-2004, 04:55 PM
Hi,

Okay, then the lag is coming from loading the textures. You can do two things. Preload all the textures and save them into a list. Or, when you add the textures, you can tell Vizard to use any existing texture with the same filename.newtexture = viz.add(texture,viz.TEX_2D,1)I would recommend that you simply preload all the textures into a python dictionary. I'm assuming the variable 'emotion' is a string.#The following code will cache the emotion textures

#Create a python dictionary
self.emotionMap = {}

#A list of all the different emotion names
emotionNames = ['happy','sad','angry']

#Iterate through emotion names and load texture
for emotion in emotionNames:
texture = self.prefix + '_Bio_UV_Head' + emotion + '.jpg'
newtexture = viz.add(texture)
newtexture.wrap(viz.WRAP_S,viz.REPEAT)
newtexture.wrap(viz.WRAP_T,viz.REPEAT)
#Save the texture in the emotion map
self.emotionMap[emotion] = newtexture

#Now your changehead method should look like this
def changehead(self, emotion):
self.head.texture(self.emotionMap[emotion], 'geom_0')

vjonshih
11-30-2004, 05:08 PM
A million and a half thanks, Farshid!

That worked like magic.