New procedural geometry samples

Hi guys,

Lately I’ve been working on some new samples for Panda3D that deal with procedural geometry creation and manipulation. See the pull request on GitHub.
You can find the samples in the attached .zip file:
procedural_geometry.zip (986.9 KB)

The old procedural-cube sample has become quite outdated and recently there were comments about its code not being that great either, so I made an attempt to improve upon it by using a different algorithm to define the sides of the cube.
Firstly, all of the vertices are now added to one single Geom instead of creating a separate Geom for each side.
Secondly, there’s no good reason anymore to call set_two_sided(True) to ensure that all triangles are visible, as the vertex indices are now correctly ordered in counter-clockwise fashion when adding them to the GeomTriangles.
Thirdly, instead of making use of GeomVertexWriters, my version uses memoryviews to access vertex data.
To make things more interesting, I’ve made it possible to add and delete any of the cube’s sides at runtime by direct vertex data manipulation.
All this can be found in the advanced.py sample.

So what’s in basic.py and medium.py then? They both show how to create just a simple square, as well as the importance of counter-clockwise winding order for backface culling; the difference is that basic.py is the only sample in the package that makes use of GeomVertexWriters.

Apart from cube creation, this code package allows you to create 5 standard 3D model primitive types: box, sphere, cylinder, cone and torus. Dedicated classes were implemented for this purpose, which you can find in the src/prim subpackage. There is the ModelMaker base class (in src/prim/base.py), which is more or less modelled after Panda’s own CardMaker class but uses properties rather than getter/setter methods to access creation parameters, and the BoxMaker, SphereMaker etc. classes derived from it (in src/prim/box.py, src/prim/sphere.py etc.).
And there are lots of parameters for each primitive type, such that a variety of shapes can be created that sometimes differ greatly from the default shape.
The primitives_showcase.py demo has been specifically provided to quickly check out the results of changing some of the creation parameters in a text file that is parsed to generate the corresponding model primitive.
Each of the parameters is documented in the __init__ methods of the classes.

For example, here’s what a torus could look like:

The resulting models can have multiple distinct surfaces, e.g. a cylinder has its main round surface, as well as two end caps. The default UV-mapping might not be what you want, so there’s a tex_units property that allows you to specify the size of a texture - not in pixels, but in object-space units, to easily achieve uniform texture mapping across the model.
The images below show a box with some of its sides removed; the first one has default UV-mapping, while the second one has the same tex_units value for all of its sides:

And here some additional transformations were applied to the UV’s of each side:

About these classes, what do you guys think, would it be nice to have these added to the Panda3D codebase?
Right now you have to resort to a modelling program and pray that nothing funny happens with export/import, just to get some basic shapes into your scenes. For testing or rapid prototyping, I think this would be more useful than having to load_model("smiley") all the time, to the point that you’re turning into a “frowney” yourself :wink: .

EDIT
You can now download the model-generation code separately from this GitHub repository.

Anyway, let’s get back to the samples. Both primitives_assembly.py and growing_vines.py are actually more like demo’s. Since I don’t feel like writing more than a thousand words about them, here are some pictures:

Enjoy the show!

There is one final thing I’d like to mention about these samples: they all use a custom GUI system. Not only are the widgets made up of the aforementioned procedurally generated primitives, their positions and sizes are also entirely controlled using a system of “sizers”, which maintain their layout when resizing the window. See the code in src/gui if you’re interested in how it works.

11 Likes

Can’t wait to look into and learn a lot from this! Thank you very much, very cool! :star_struck:

Hah, just saw this now, I remember you helping me out with cubes a while back… Awesome job! That vine thing looks especially interesting…

I spent the past few days coding again, working on my own procedural generation system. My endgoal is to create virtual creatures, and I finally got my system working in it’s most basic form.

The idea is to start out with a base triangle, which you then pass barycentric coordinates to and extend a point from there, creating a tetrahedron. Basically you can repeat this operation as many times as you want, and it should work well with random generation.

I think I’ll also include a class for generating cube based structures later, but now I need to figure out how to get the thing moving, because I don’t plan on using rigging that changes the actual geometry. I’m considering each generated geom as a bone, that is attached to a joint.

But I haven’t started researching this stuff, because I just finished the generation algorithm today.

Thanks :slight_smile: !

Sounds very interesting!

That reminds me that I should implement polygon extrusion as a modelling tool in my own project (Panda3D Studio). Hopefully “soon”…

Argh, animation. Yeah that’s gonna be quite a challenge for me as well, haha!

Good luck to us both then!

Thanks man!

And please tell me once you finish this, It’d be interesting how you would do that. Whenever that soon™ might be😉

The BoxMaker and other maker classes would be very helpful if they could be added to panda3d or pip installed via separate library :open_mouth: .

Great work there!

You can now download them from this GitHub repository as a separate Python package.
Not sure if/when I’ll be able to make the package available through pip, though.
Just moving the procedural3d directory to your project source code should hopefully be simple enough.

Thank you very much, and I hope it will be useful to you! :slight_smile:

Thank you so much! I’m still going through the files and learning!!! Why can I not find a full list of accept “mouse” strings? For example from the documentation?

https://docs.panda3d.org/1.10/python/reference/direct.showbase.DirectObject#direct.showbase.DirectObject.DirectObject.accept

Where is the missing documentation?

I guess you’re looking to accept mouse event ? You’ll find this part of the doc may be useful in your case (for hardware and event in general):

https://docs.panda3d.org/1.10/python/programming/hardware-support/index

And the mouse oriented part will be this one in the same sections:
https://docs.panda3d.org/1.10/python/programming/hardware-support/mouse-support

Hope this can answer your question, feel free to ask if not :slight_smile: