I’m trying to generate a complete actor, including procedural textures via pixel shaders, generated mesh, generated skeleton hierarchy and dynamic animation feed in Panda3D using Python scripts only (ie. no C++ and no external files) and without changing the existing Panda3D code.
Ignoring the actual animation for now, I’m currently facing problems with generating the skeleton hierarchy (bones / joints). Essentially I want to generate a standard skeleton hierarchy with vertex references (ie. one that would be compatible with eg. loadAnim() and the LerpAnimInterval class as long as the animations match the skeleton). Is there any way to do this without resorting to using the egg loader? If not, can I do this without resorting to generating egg syntax (eg. using the Egg classes)?
I can easily generate a mesh with procedural textures using setShader() and the Geom related classes (GeomVertexData et al). The resulting mesh can be attached to an actor using loadModel(), but it won’t contain any useful skeleton data (and a warning message is printed indicating this). If I understand the code in Actor.py correctly, then joint information will only be honoured if the provided model is or contains a Character object.
I’ve tried creating a Character object directly, but python simply won’t let me; it complains that the class is constant. I’m relatively new to Python, but I’m guessing this is part of the metadata for the exported C++ class and not overridable from Python code (and if so, then presumably there’s a good reason for this constraint).
Loading an egg file that contains a character will result in a Character object parented to the returned object. So evidently the egg loader can create those. So far I’ve found no other way to create Character objects.
According to this page you can generate egg data dynamically and load it without actually creating any egg file, by using EggData() and its subnodes. There is an isJoint() member of the EggNode class, which suggests a joint in the egg domain is either an EggNode object or an object of a class that directly or indirectly inherits it, but I can’t seem to find a way to create such joints using these API functions.
My last resort, then, is to generate a string containing egg syntax and have it loaded from a StringStream object. This approach has been confirmed to work with egg data in general, and I see no reason why I wouldn’t be able to include joints this way.
Looking at the syntax description on this page it is apparent that this would have some rather awkward consequences, even beyond being relatively ineffective since it obviously requires string parsing and probably a few additional layers of data restructuring.
For a node to be effective, it needs to contains nodes. Each node has a list of vertex indices and a node pointing to a vertex pool.
If I have to generate egg syntax, I would much prefer to stop at that point. This would require that I have the ability to create a named vertex pool programmatically and somehow map it to the generated vertex list. I’ve found no way to do so (the closest thing I’ve found is the EggVertexPool class, which appears to be used only during loading, and in any case it seems to have no exposed functionality related to GeomVertexData objects).
Furthermore, the egg loader complains about the pool not being defined unless I include a node in the egg syntax. If I do this, the egg loader complains about any vertices not defined using nodes. In other words, I seem to be forced to include the entire model in the egg syntax, instead of generating the mesh with the Geom classes. This is still workable as long as I can map my shaders to egg materials, but extremely awkward.
Did I miss anything? Is there a better way to do this?