thirdparty development :?:

I am going to try to write a c++ module for Panda3D, but before I can begin I have a couple of questions.

First of all it looks like i could place my files(header and lib) in the thirdparty directory. Is it possible to create a new folder and then use the
–thirdparty “mydir” command to get it included?

I have inspected some of the header files in the different thirdparty tools and it seems like a special keyword PUBLISHED: is used for creating a python wrapper. I cant seem to find much information on this in the doc dir, but maybe some of you could point me in the right direction?

How can I add my module to the panda source-tree?


The thirdparty directory is actually a collection of general-purpose third-party libraries that Panda uses, for instance libjpeg and zlib. It’s not actually a place to put third-party contributions to Panda (we don’t have such a directory set aside at this point).

The right way to add C++ code to the Panda source tree depends on the level of integration with Panda required. Since you used the word “module”, I infer that you intend to develop some C++ code that links with libpanda.dll, and also can be loaded into Python.

Of course, you could simply use Visual Studio (or your development environment of choice) and point your include directory at panda3d/include and link with the lib files in panda3d/lib. But this won’t automatically generate wrappers for Python, and it will be difficult to share your code with other users later if you decide to contribute it to our public codebase.

But if you integrate with the Panda build environment, you will get Python wrappers for free, and it will be easy to distribute your code.

To use Panda’s build environment, you will need to create a directory hierarchy populated with Sources.pp files, like direct. In fact, you will probably find it easiest to follow the example presented in the direct tree. In each C++ directory, there is a Sources.pp file that lists the .h and .cxx files that are to be compiled together. There is also a direct/metalibs/direct/Sources.pp that builds the overall libdirect.dll; note the line COMPONENT_LIBS which lists each of the component directories that go into the dll.

You can copy these files into a separate hierarchy of your own, changing names here and there as appropriate. You will also need Package.pp in the root directory of direct.

When you have these files in place, you should be able to run ppremake and make install to build your code.

The keyword PUBLISHED is indeed used to mark methods that are to be made available to Python. It is akin to C++'s public, private, and protected; think of it as an uber-public. With the Sources.pp tree in place properly, the PUBLISHED keyword is all you need to use to expose your methods, although you will also need to add your new dll to the genPyCode command line after you have run make install:

genPyCode mynewlib.dll


By “thirdparty,” I pretty much mean “software that is used by panda, but isn’t a part of panda.” Things like openssl, libpng, that sort of thing.

If your code is an enhancement to panda itself, then it would go in the main panda tree, I’d say.

Thank you David and Josh for clarifying this. I will try your approach and see if I can get it to work. :laughing:

Hi again

Okay forget the “third-party” stuff I talked about earlier David was right defining my goal as “developing some C++ code that links with libpanda.dll, and also can be loaded into Python”.

I am using Visual Studio .NET 2003 and have for testing purpose made a small C++ solution that have one method which adds two numbers and returns the result. I have the Panda source code on my computer and I have successfully used the makepanda “–everything” to build it.

I don’t know if any of you have the time to guide me through the next steps, becuase I get a little confused when reading your post. Do I have to use the ppremake or can I make some adjustments to the makepanda?

hmm maybe it makes more sense when reading the post again :bulb: i’ll be back

Thank you for a great engine

Okay here we go again. I now have this test program.

and the headerfile


Maybe I could just create a new folder in the \direct\src dir called mymodule and place these files in here for testing purpose?

Does this look correct and would this enable me to use makepanda or am I missing some greater point? Sorry for the noobness :blush:


  • Andreas

“Do I have to use the ppremake or can I make some adjustments to the makepanda?”

Makepanda consists of two halves. The first half is complicated. The second half is a long list of compile and link commands. You just have to add another file to the long list.

Let’s start easy. Let’s add a new class to the “mathutil” library. Add your files “astar.h” and “astar.cxx” to the mathutil directory. Then, see if you can get your files to compile. Look in makepanda for these compile commands:

CompileC(ipath=IPATH, opts=OPTS, src=‘mathutil_composite1.cxx’, obj=‘mathutil_composite1.obj’)
CompileC(ipath=IPATH, opts=OPTS, src=‘mathutil_composite2.cxx’, obj=‘mathutil_composite2.obj’)

Add another one:

CompileC(ipath=IPATH, opts=OPTS, src=‘astar.cxx’, obj=‘mathutil_astar.obj’)

Then, look for where “mathutil_composite1.obj” is linked into “libpanda”. It’s a giant list of all the obj-files that get included in libpanda. Add your obj-file to the list of obj-files that are included in libpanda.

Now test it. See if it compiles.

Next, your goal is to see if you can call your addition function from python. A program called “interrogate” has to generate stubs for your math class. Look in makepanda until you find the “interrogate” command that interrogates “mathutil_composite1.cxx”. Add your files (both of them) to the list of files that it interrogates. You will also have to use the keyword “PUBLISHED” to your header file to tell interrogate which functions to export.

Compile it again. This time, it should be possible to import your class from pandac.PandaModules, and it should be possible to call your function.

Let’s get you that far, and see how it goes.

Panda3d has two build systems: makepanda and ppremake. They’re completely separate, it’s necessary to pick one and ignore the other.

Which should you use? My general feeling is that if you’ve already got one of them to work, then there’s no reason to switch. Because of that, I’d say, stick with makepanda for now.

The steps you took with “Sources.pp” are relevant only if you’re using ppremake (any file that ends in “pp” controls ppremake). Since you’re not using ppremake, let’s set that file aside for the moment.

After a few trial and error attempts I finally managed to get it working.

I did change the following

CompileC(ipath=IPATH, opts=OPTS, src=‘astar.cxx’, obj=‘mathutil_astar.obj’)


CompileC(ipath=IPATH, opts=OPTS, src=‘AStar.cxx’, obj=‘AStar.obj’)

Don’t know whether it’s case sensitive or not but this worked for me.

I also had some trouble getting interogate to create wrappers for the code but by using BEGIN_PUBLISH and END_PUBLISH and deleting before recompiling did the trick.

Thanks for all your help so far Josh

Hi again

I was wondering if the following class would work as it is, or if some special tweaking is required?

I have not added the PUBLISHED stuff yet, but I guees that shouldnt matter for the compilation part.

I think my question really boils down to how templates and pointers are handled. :confused:


I don’t see any problems so far. But does it compile? Does it run? That’s your real answer.

Still, if you are interested in producing code that is to be used in Python, I would recommend avoiding template classes, except in small self-contained areas. Template classes don’t translate very well to Python.

Within most of the Panda3D C++ codebase, we have endeavored to keep things like STL vectors internal to a class, and only expose accessors like get_element() and get_num_elements(). Much safer. And we generally don’t use template classes for the big picture stuff.

We actually started out being much more heavily template-driven. All of the linmath stuff, the points and matrices, for instance, were template classes. The config variables were all template classes. Even our node class was a template class at one point. It really got out of hand and caused all sorts of difficulties down the road, including problems with poor compiler support, especially cross-DLL linking, long compilation times, unneeded object code replication, and difficulties wrapping the whole thing in Python.

We finally got fed up with templates and went on a big template purge. We moved the linmath library to a poor man’s template instantiation, using #define and #include in unusual ways. Other templates we just eliminated altogether. Now we still use templates, but they’re must more constrained; and since then things have been much better.

I’m not saying templates are bad; but like any powerful tool, they can be used for good as well as for evil. Tread carefully. :slight_smile:


Hei again
Okay I dont know if you have the time for this one, but I think i have missed something important. First my three header files:



and last PFPosition.h

in I have inserted the following lines. PFPosition.h and PFNodeStar.h are the ones containing the PUBLISHED statement so I only add them to the Interrogate, is this correct?

and later in the same file i have added:

At last i have made two files pathfind_composite1.cxx and pathfind_composite2.cxx

pathfind_composite1.cxx contains PFPosition.cxx and PFNodeStar.cxx, and pathfind_composite2.cxx only has PFNode.cxx

the strange thing is that I get a parse error from the composite1 file.

I have succeded in doing something almost like this, but this wont work. Espacially im interested in if any imports like the #include “pandabase.h” is indeed needed?

This is a large post I know, but any pointers would really be appreciated 8)

Best regards

By this, do you mean to say that your contents of pathfind_composite1.cxx are:

#include "PFPosition.cxx"
#include "PFNodeStar.cxx"

and the contents of pathfind_composite2.cxx are:

#include "PFNode.cxx"



Yes excatly :astonished:

Well, what is at line 3, column 10 of pathfind_composite1.cxx, then? There appears to be something there that interrogate does not recognize as valid C++ syntax.


Yeah and I cant seem to grasp what it is. Do you know why there is an empty line before the includes, and two after in all the composite files?

And does it matter where I put my files like is there a diffrence between pathfind_composite1.cxx and pathfind_composite2.cxx?

Is the #include “pandabase.h” required in some cases?

10 more questions for the professor, thanks for bearing with me

Okay placing the three .cxx files in thier own composite file did the trick. I think I have finally understood the concept, so now it is time to produce something usefull :stuck_out_tongue: