Panda3D 1.6.0 released

Oh boy, lots of different things to reply to in this thread. :slight_smile:

In addition to pro-rsoft’s explanation of asynchronous loadModel(), you can further ask textures to be loaded to the graphics card asynchronously. This means that the first time you look at a particular model, the texture might not be available; but instead of holding up the frame while we wait for it to be loaded, Panda can render the model immediately, with a flat color instead of the texture; and start the texture loading in the background. When the texture is eventually loaded, it will be applied. This results in fewer frame-rate chugs, but it means that the model looks a little weird at first. It has the greatest advantage when you are using lazy-load textures as well as texture compression, because it means these things will happen in the background. Try setting:

preload-textures 0
preload-simple-textures 1
texture-compression 1
allow-incomplete-render 1

As for loading animations asynchronously, a similar behavior can be enabled for Actors, so that when you have an Actor with a large number of animations (too many to preload them all at once), you can have the Actor load them on-demand, so that when you play an animation, the animation may not start playing immediately, but will instead be loaded in the background. Until it is ready, the actor will hold its last pose, and then when the animation is fully loaded, the actor will start playing where it would have been had the animation been loaded from the beginning. To make this work, you have to run all of the animations through egg-optchar with the -preload option, and you might also want to set:

restore-initial-pose 0

Seems likely. I’ll investigate.

It just means that the FadeLodNode does a better job of fiddling with the depth buffer settings during the fade transition, to minimize flickering from coplanar polygons of your two different models. I don’t know that this has anything at all to do with normal mapping. I guess if normal mapping is enabled on one or both details, it might get handled properly as a matter of course; but since this involves the ShaderGenerator (and therefore a shader recompile at each stage of the transition), performance might be a limiting issue.

David

Thanks for the explanation! That does sound really useful. Would this functionality be useful alongside the loadAnim/unloadAnim methods of the Actor class, or would I not need to bother with asynchronous loading of animations while using those commands?

In a future project (ie. after I’ve developed a few other things to get really familiar with Panda) I expect to have characters with so many animations that it might be problematic to have all the animations loaded at once, so I was thinking of writing a system that loads up the animations that are likely to be needed next and unloading animations that aren’t needed anymore.

Actually, the Actor has always supported on-demand loading of animations; and that is its default behavior. Calling loadAnims() doesn’t actually load anything from disk; it just specifies that filenames that will be loaded when each animation is played for the first time.

In order to force an animation to actually load, you can either play it or call bindAnim(). This will result in a frame hitch in the traditional Actor code as the animation is actually loaded from disk. In the new 1.6.0 Actor, with the -preload in effect, playing an animation (or calling bindAnim()) starts the animation loading in a thread, so there is no frame hitch. You can call waitPending() to make it stop and wait for all of the pending animations to become available (for instance, during a loading screen).

The normal behavior is to cache each animation the first time it is loaded, and then keep it around until the Actor is destroyed or until unloadAnims() is called. If you really want to recover the memory, you should also call ModelPool.releaseModel(), but only when you are sure that all Actors that share the same animation file have unloaded it. (Since the animation data is essentially a static table, different instances of Actor that load the same animation egg file will actually just share a pointer into the common memory. This common memory will remain resident until all Actors, and the ModelPool, release it. If you release it from the ModelPool prematurely, the next Actor to load it will be forced to re-read it from disk, wastefully duplicating the table already in memory for the other Actor(s).)

David

This was indeed the problem, and I’ve just checked in the fix and tagged it for the 1.6 branch. PandaSneezes.avi once again loads properly.

David

Congratulations on the new release:-)

Are there any changes relating to ODE that have been omited from that change list btw?
Just wondering because after installing 1.6.0 my previously smooth game has become jerky, and I don’t mean frame rate - its something to do with ODE fighting how I move the player and making the players viewpoint jitter when moving.

Ah, ok, cool. I’m still in the planning/idea phase, I haven’t really implemented much at all. In fact, I think I’m going to wait for the stable 1.6.x release (or whenever the first 1.6.x bug fix release hits) and start from scratch. I keep changing ideas, started out as the most simple version of everything and concentrate on the game. Now I think I want to make a simple game but use the more advanced functions such as ode and concentrate on learning them well. I’ll just wait for whenever the new shadow functionality hits before worrying about that.

@drwr: Great, thanks!

Now that you mention it, yes, theres a new collision event system. I’ve been very careful with preserving performance though, so are you very sure it’s not something else causing the problem?
Otherwise, make me a simple testcase that works better in 1.5.4 than in 1.6.0, so I can reproduce the problem.

self.cTrav.showCollisions(render)

doesn’t work in 1.6.0. I tested it with the Roaming Ralph sample. No problem in Panda 1.5.3.

I would also please to see a documentation (e.g. in the reference) for the functions setX,Y,Z,Pos which can set the positions also relative to another node like it’s now done in the new version of the Ralph sample.

Aah, fair enough, and thanks. :slight_smile:

I’m glad to hear that the depth issue has been improved - thank you for that. :slight_smile:

As to normal mapping, I mentioned a problem with the combination of normal mapping and FadeLODNode in my old forest rendering thread; it was mentioned there, I believe, that support for the particular element that was producing numerous error outputs at the time (ColorScaleAttrib, I believe) had been included in the CVS version, and “Should be in 1.6.0.” - while I had forgotten the details before looking my old thread up again, that was, I think, what I was asking after.

Yes, the shader generator now supports color scales.
(Note that there’s also the non-shader NodePath.setNormalMap equivalent)

I forgot to respond to this question:

Yes. You can do this:

from direct.showbase import VFSImporter
VFSImporter.register()

This enables you to import Python files using Panda’s VFS, which means that all you need to do is mount a MF file and add the mount point to sys.path, and you’re off and running.

Note that this mechanism is also used by direct/showbase/RunAppMF.py, an experimental tool which can run an entire application (including bam files and python files) bundled into an mf file. This works in conjunction with MakeAppMF.py, which constructs an appropriate mf file from a directory hierarchy. These two tools are just a proof-of-concept right now, but the ultimate idea is to have a “panda player” which consists of something like RunAppMF.py bundled into an executable, so that people only have to distribute their apps as mf files. I also hope to be able to distribute this panda player as a browser plugin, so this is how we will support running Panda apps in a browser window.

David

Hmm, if ctrav.showCollisions() isn’t working, is it possible that this release was accidentally built with OPTIMIZE=4 instead of OPTIMIZE=3? Building with OPTIMIZE=4 turns off some of these debugging tools and also disables certain error checks and assertion tests, to squeeze out the last drop of performance. But it’s not a good idea to attempt to do development on a build made this way.

David

I highly doubt it. What OS are you on, neo?
I’m 100% sure at least the Linux builds have optimize level 3. Treeform made the windows build.

Sorry, it’s Windows (XP SP2) like you correctly assumed. But after more testing I have more problems with the threading module of panda. Don’t work like the usual python threading modul. E.g.

from direct.stdpy import threading

class TestClass(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    
    def run(self):
        pass

t = TestClass()
t.start()
t.join()

brings the error:

Adding a name to the init:

threading.Thread.__init__(self,name="test")

solves this problem and goes to the next one:

Here is the real problem, that the thread don’t start. Maybe someone who wrote this module spent some time to expand the manual and explains its usage.

Hmm. I can fix the Python errors in the threading module, but if the thread didn’t start, it must be a configuration error in the Panda build. Perhaps threading didn’t get properly enabled for some reason? Check Thread.isThreadingSupported().

David

I confirm the release optimization level on Windows. It causes very random crash when I use a C++ extension. It runs perfectly fine on Linux.

I’m wondering, who set depth buffer bits to only 16 in Config.prc ? I used to the default 24.
It surprised me suddenly the depth buffer was just like GeForce2’s. :stuck_out_tongue:

And why the model cache is not enabled by default on Linux ?

I have a question about the TaskManager. Since it’s multithreaded, calling step() gives me an assertion error of num_busy_thread==0 or so. My Q is how should I safely force the whole loops to be done in the middle of a frame ? Meanwhile, I simply call some of the loops I need with respect of their priority order.

And about the absence of collision visualizer, I’ve seen it since a month ago CVS, OPTIMIZE 3. Not sure if it was broken earlier.

Hmm, I’m confused. I don’t think you should be getting an assertion, even with multithreading enabled. I also don’t understand what you mean about forcing loops to be done. Can you show me some sample code that illustrates the problem?

David

I mean dataLoop, igLoop, and the rest of them. Simply calling taskMgr.step() during dataLoop (upon any input) gives me the assertion error.

EDIT :
sorry, it happens anytime after run()

Wait, you mean you are recursively calling taskMgr.step() from within a task? Yeah, that’s not supported; it was never intentionally supported before, but I guess it might not have triggered an error before.

If you want to yield the task, why not try the new Python generator feature of the TaskManager, where you can actually just use “yield Task.cont” command to return control to the TaskManager and come back next frame.

David

Not necessarily in a task. I just need those 2 loops, though, and calling them directly seems enough. Its purpose is to immediately stops repetitive slightly-heavy-weight function calls when a key is released (I’m talking about -repeat event), if keyboard rate is so high on Linux, unlike most apps which stops it only when the buffer is drained.

Thanks.