Last active
June 6, 2023 18:09
-
-
Save rdb/81853af7538ebf9ba6a8281ab9a0435b to your computer and use it in GitHub Desktop.
This gist demonstrates how to use the new .bam reading hooks to define custom types in Python or define a loader hook for existing types. Requires Panda 1.10.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| This example shows how to use the new Python factory function in the BamReader | |
| in order to add a custom hook that is called when the BamReader encounters an | |
| object of a certain type. | |
| You can also use this to add a custom hook whenever the bam reader loads an | |
| existing type, for example if you want to do some post-process task on every | |
| GeomNode or Material loaded from the .bam file. | |
| """ | |
| from panda3d.core import BamReader, TypeRegistry, PandaNode, NodePath | |
| registry = TypeRegistry.ptr() | |
| # This shows how to register a custom factory function for any type that the | |
| # Panda type system knows about. In this case, it's an existing type, | |
| # PandaNode. | |
| # The callback does nothing interesting but print a message and add something | |
| # to the name. | |
| def node_factory(scan, reader): | |
| print("Reading PandaNode from .bam file with version %d.%d" % (reader.file_version)) | |
| node = PandaNode("") | |
| node.fillin(scan, reader) | |
| node.name += " (MODIFIED)" | |
| #NB. Note that at this time, all the pointer values (eg. node.state, | |
| # node.get_children(), etc.) have not been filled in yet! | |
| return node | |
| # Register our custom hook function, overriding the existing PandaNode loader. | |
| BamReader.register_factory(PandaNode, node_factory) | |
| # Now follows a more complete example that uses a custom type that inherits | |
| # from PandaNode. Creating a class and providing these methods isn't | |
| # necessary, as the above example shows, but this follows the Panda paradigms. | |
| class CustomNode(PandaNode): | |
| def fillin(self, scan, reader): | |
| PandaNode.fillin(self, scan, reader) | |
| # Also read out a custom field that this class adds. | |
| self.custom_field = scan.get_uint8() | |
| # Here's how to read a field that depends on the .bam version. | |
| if reader.file_version >= (6, 42): | |
| self.new_field = scan.get_uint8() | |
| else: | |
| self.new_field = None | |
| @staticmethod | |
| def make_from_bam(scan, reader): | |
| """Factory function that is called when the .bam reader encounters an | |
| object of type CustomNode.""" | |
| node = CustomNode("") | |
| node.fillin(scan, reader) | |
| return node | |
| # Register our custom type with Panda's type system, telling Panda that the | |
| # class inherits from PandaNode. | |
| class_type = registry.register_dynamic_type("CustomNode") | |
| registry.record_derivation(class_type, PandaNode.get_class_type()) | |
| # Register the factory function with the BamReader. | |
| BamReader.register_factory(class_type, CustomNode.make_from_bam) | |
| # Test loading a file. | |
| from panda3d.core import ModelPool | |
| node = ModelPool.load_model("test.bam") | |
| NodePath(node).ls() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment