**Bam Format**
# Bam Format
This is the technical documentation for the .bam format. This is
generally not useful except for developers who insist on writing their
own tools to manipulate .bam files without using the Panda APIs.
## Bam versions
The .bam format has a major.minor version scheme. The format is designed
to be backward compatible, so that .bam files created with older
versions of Panda3D will generally work with newer versions of Panda3D,
although occasionally compatibility has been broken due to major changes
in the Panda3D structures.
Forward compatibility is not considered, though, so Panda3D will refuse
to read .bam files with a higher version number. This means you can read
Panda3D 1.8 bams in Panda3D 1.9, but not vice versa.
As of Panda3D 1.7.1, We try not to bump the .bam version between minor
releases of Panda3D, so that .bam files created with Panda3D 1.8.1 will
still load in Panda3D 1.8.
The table below shows the .bam version associated with each Panda
release. The first column shows the Panda version, the second shows
which version .bam files it will output (and also the maximum that it
will read), and the third shows the minimum .bam version that it will
read.
| Panda version | Writes | Reads |
| ------------- | ----------- | ----- |
| 1.0.x | 4.14 | 4.0 |
| 1.1.0 | 5.4 | 5.0 |
| 1.1.1 | 5.6 | 5.0 |
| 1.2.x | 6.3 | 6.0 |
| 1.3.x | 6.4 | 6.0 |
| 1.4.x | 6.12 | 6.0 |
| 1.5.0 | 6.14 | 6.0 |
| 1.5.1, 1.5.2 | 6.15 | 6.0 |
| 1.5.3, 1.5.4 | 6.16 | 6.0 |
| 1.6.x | 6.14 | 6.14 |
| 1.7.0 | 6.22 | 6.14 |
| 1.7.1, 1.7.2 | 6.24 | 6.14 |
| 1.8.x | 6.30 | 6.14 |
| 1.9.x | 6.37 | 6.14 |
| 1.10.0-1.10.5 | 6.21 - 6.44 | 6.14 |
| 1.10.6-1.10.9 | 6.21 - 6.45 | 6.14 |
Note that Panda3D 1.10 is able to write older .bam files. This can be
done by putting this in Config.prc:
```
bam-version 6 21
```
When not set, the default is to write the latest supported version
that is still readable by the .0 version of that release branch.
For example, 1.10.6 through 1.10.9 will write bam 6.44 by default.
## Bam header
The bam format is composed of a series of datagrams. Each datagram is
prefixed by an unsigned 32-bit size number. Exceptionally large
datagrams are encoded by writing 0xffffffff as the size, followed by an
unsigned 64-bit integer containing the actual size.
Most .bam structures are stored in little-endian format. Certain
structures can be stored in a different endian format, where specially
tagged as such. Currently, this applies to vertex data. The endianness
of this special data is indicated by the file header.
.bam files (but not .bam streams) begin with the six-character magic
string `pbj\0\n\r`. This can be used to uniquely identify .bam files. It
includes a carriage return and newline character to help detect files
damaged due to faulty ASCII/binary conversion.
This is followed directly by the file header, the structure of which is
detailed below. When a version number is indicated, it indicates that a
field has been added in that version, so a backward compatible reader
should not read that field if the .bam version is lower than the
indicated number.
| Bytes | Type | Name | Minver | Description |
| ----- | ------ | ---------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| 4 | uint32 | | | Size of header datagram (should be 6) |
| 2 | uint16 | bam_major_ver | | Major .bam version, as detailed above. |
| 2 | uint16 | bam_minor_ver | | Minor .bam version, as detailed above. |
| 1 | uint8 | file_endian | 5.0 | Endianness of vertex data (everything else is little-endian). 0 if big-endian, 1 if little-endian. |
| 1 | bool | stdfloat_double | 6.27 | True if fields marked "stdfloat" contain 64-bit floating point numbers instead of 32-bit. Before 6.27 they were implicitly 32-bit. |
## Objects
What follows the header is essentially a list of objects. There is
usually (but not necessarily) a single root object at the beginning, and
all children and other dependent objects follow. For a .bam file
containing model/animation data, this is the root node of the scene
graph.
Each object has a sequentially increasing unique ID, by which it is
referenced by other objects. The special ID 0 is reserved to indicate a
NULL pointer.
Of note is that object IDs are stored as 16-bit unsigned integers, but
as soon as an object with ID 65535 is encountered, all future object IDs
and references to it are stored as 32-bit integers.
An object may occur more than once in the .bam stream, for example if it
was modified since it was first written.
The first time an object is written it also specifies type information.
Each type is identified with an arbitrarily chosen type index, followed
by the name of the type. It also contains hierarchical information about
the parent classes, which is useful when a reader does not understand
eg. a PandaNode derivation but will still be able to reconstruct the
base node. Information about each type is only written the first time a
type with a particular index is encountered.
## Object stream
Before version 6.21, the header was followed by a continuous stream of
objects. This means that in order to determine whether the object and
its dependencies have been completed, the reader must keep track of the
number of objects referenced
Version 6.21 resolves this by inserting special codes in the object
stream that can be used to specify a nested structure of objects. When
writing out an object, a `push` code is first inserted, after which the
object is written out, followed by the objects that were referenced the
object, each of them also prefixed by an object code. Only then is the
`pop` written out, indicating that the object is complete.
Of course, the dependent objects themselves may write nesting `push` and
`pop` codes, so in order to determine whether an object structure has
been completely read, it is necessary to count the number of `push` and
`pop` codes encountered.
The object code is a single 8-bit integer that can take on the following
values:
| Value | Name | Description |
| ----- | --------------- | ---------------------------------------------------------------------------------------------- |
| 0 | BOC_push | Increments the nesting level. Followed by a single object definition. |
| 1 | BOC_pop | Decrements the nesting level. Followed by another object code. |
| 2 | BOC_adjunct | This code is followed by a single object. This is the implied value before 6.21. |
| 3 | BOC_remove | Followed by a list of object IDs that are no longer important to the file and may be released. |
| 4 | BOC_file_data | Followed by an auxiliary data record that may be requested by certain objects. |
As an example, this is what the structure looks like for a node
referencing two different textures:
```
PUSH PandaNode ADJUNCT Texture ADJUNCT Texture POP
```
Since it may be difficult for a writer to know before writing an object
whether it will reference other objects, the following is also perfectly
legal:
```
PUSH PandaNode PUSH Texture POP PUSH Texture POP POP
```
## Type encoding
Unless specified otherwise, all integer types are little-endian. (Note
that there is an endianness field in the header, but it only affects
geometry buffer data.)
- bool:
Booleans are stored as a single byte that is either 1 (for true) or
0 (for false).
- string:
Strings are encoded as a uint16 length indicating the number of
characters that directly follow.
- stdfloat:
Usually float32, but can be float64 if stdfloat_double in the
header is set to 1.
- pointer:
An integer identifying the referenced object. 0 represents the NULL
pointer. This is uint16 until object ID 0xFFFF has been encountered
in the stream, then it becomes uint32.
Arrays of multiple objects are usually expressed by first outputting a
length field, which itself can vary on size depending on how many
objects are usually present in this array.
## Object reference
This is an incomplete list of objects and their .bam encoding scheme.
The "minver" column indicates which bam version the field was introduced
in; if writing a bam file with a version older than that, the field
should not be written out.
Blocks in grey indicate either an optional field (the presence of which
depends on the value of the indicated other fields) or a block that is
repeated for each element in an array (usually indicated by a preceding
length field).
### Geom
|
pointer |
data |
Non-0 pointer to GeomVertexData object. |
|
uint16 |
primitives |
The following field is repeated for each primitive: |
|
pointer |
Non-0 pointer to a GeomPrimitive object. |
|
|
uint8 |
primitive_type |
Base primitive type of all primitives, should be one of the following: |
0 |
PT_none |
Used only for empty primitives. |
1 |
PT_polygons |
Used for triangles and tristrips. |
2 |
PT_lines |
|
3 |
PT_points |
|
4 |
PT_patches |
|
|
|
uint8 |
shade_model |
See geomEnums.h. Set to 1 for SM_smooth, the default in Panda. |
|
uint16 |
reserved |
Not used. |
6.19 |
uint8 |
bounds_type |
Default 0. |
### GeomNode
|
PandaNode |
base class |
|
|
uint16 |
geoms |
The following block is repeated for each geom: |
|
pointer |
geom |
|
pointer |
state |
|
### GeomVertexData
|
string |
name |
|
|
pointer |
format |
Non-0 pointer to a GeomVertexFormat object. |
|
uint8 |
usage_hint |
Set to 3 for static objects, 2 for dynamic, 1 for streamed vertex data. |
|
uint16 |
arrays |
The following block is repeated for each array: |
|
|
pointer |
transform_table |
May be 0 for non-skinned objects. |
|
pointer |
transform_blend_table |
May be 0 for non-skinned objects. |
|
pointer |
slider_table |
May be 0 for objects without morphs. |
### GeomVertexArrayFormat
|
uint16 |
stride |
|
|
uint16 |
total_bytes |
|
|
uint8 |
pad_to |
|
6.37 |
uint16 |
divisor |
Attribute divisor. Set to 0 for vertex data, 1 for instance data. |
|
uint16 |
columns |
Repeated for each column: |
|
pointer |
name |
|
uint8 |
num_components |
|
uint8 |
numeric_type |
|
uint8 |
contents |
|
uint16 |
start |
6.29 |
uint8 |
column_alignment |
|
### GeomVertexArrayData
| Minver | Type | Name | Description |
| ------ | --------- | ------------- | -------------------------------------------------------------------------------------- |
| | pointer | array_format | Non-0 pointer to GeomVertexArrayFormat. Should be the same as in the GeomVertexFormat. |
| | uint8 | usage_hint | Should be same as usage_hint in the GeomVertexData. |
| | uint32 | buffer_size | |
| | bytearray | buffer | Buffer data. Floats are in endianness specified in the file header. |
### GeomVertexFormat
|
uint8 |
animation_type |
0 for no vertex animation, 1 for CPU animation. |
|
uint16 |
num_transforms |
Set to 0. |
|
bool |
indexed_transforms |
Set to false. |
|
uint16 |
arrays |
The following block is repeated for each array: |
|
### InternalName
This stores just a single string.
### Material
Bam 6.39 introduced a new Material structure. This is the old structure
from before 6.39:
5.6 |
string |
name |
Name of this material. |
|
stdfloat[4] |
ambient |
Must be present, but is ignored if flags does not include F_ambient. |
|
stdfloat[4] |
diffuse |
Must be present, but is ignored if flags does not include F_diffuse. |
|
stdfloat[4] |
specular |
Must be present, but is ignored if flags does not include F_specular. |
|
stdfloat[4] |
emission |
Must be present, but is ignored if flags does not include F_emission. |
|
stdfloat |
shininess / roughness |
This value is usually the specular exponent, unless F_roughness is set. |
|
int32 |
flags |
A bitmask produced by OR-ing one or more of the following: |
|
0x001 |
F_ambient |
0x002 |
F_diffuse |
0x004 |
F_specular |
0x008 |
F_emission |
0x010 |
F_local |
0x020 |
F_twoside |
0x040 |
F_attrib_lock |
0x080 |
F_roughness |
|
|
|
### MaterialAttrib
A MaterialAttrib simply contains a single pointer to a Material, which
may be 0 to indicate the lack of a material.
### PandaNode
|
string |
name |
Name of this node |
|
pointer |
state |
Pointer to RenderState object. Should not be 0. |
|
pointer |
transform |
Pointer to TransformState object. Should not be 0. |
|
pointer |
effects |
Pointer to RenderEffects object. Should not be 0. |
6.2 |
uint32 |
draw_control_mask |
Default 0. |
|
uint32 |
draw_show_mask |
Default 0xffffffff. Interpreted slightly differently before 6.2. |
4.12 |
uint32 |
into_collide_mask |
Default 0. |
6.19 |
uint8 |
bounds_type |
Type of bounding volume to be generated for this node. Default 0 (BT_default). |
4.4 |
uint32 |
tags |
The following block is repeated for each tag: |
|
|
uint16 |
parents |
The following field is repeated for each parent: |
|
|
uint16 |
children |
The following block is repeated for each child: |
|
|
uint16 |
stashed |
The following block is repeated for each stashed child: |
|
### Texture
|
string |
name |
Name of this texture |
|
string |
filename |
Filename of this texture |
|
string |
alpha_filename |
If not empty, name of a different file from which to retrieve the alpha information |
|
uint8 |
primary_file_num_channels |
If not 0, the number of channels to downgrade the image to if it is greater than this number |
|
uint8 |
alpha_file_channel |
If alpha_filename is not empty, determines which channel to take the alpha information from. 0 is to take the grayscale combination of RGB, 1 is red, 2 green, and so on. |
|
bool |
has_rawdata |
If true, the raw contents of this texture are included in the .bam data |
|
uint8 |
texture_type |
Type of texture, should be one of the following: |
0 |
TT_1d_texture |
|
1 |
TT_2d_texture |
Used for most textures. |
2 |
TT_3d_texture |
|
3 |
TT_2d_texture_array |
New in bam 6.25 |
4 |
TT_cube_map |
3 in bam version 6.24 and before |
5 |
TT_buffer_texture |
Requires Panda3D 1.10 |
|
6.32 |
bool |
has_read_mipmaps |
If true, the filename is assumed to contain a # which is substituted with an index for various mipmap levels |
|
SamplerState |
default_sampler |
The sampler settings that will be used in absence of other sampler parameters. See SamplerState entry for the various fields |
6.1 |
uint8 |
compression |
Leave 0 for default compression mode (according to compressed-textures), 1 for explicit off, 2 for explicit on (see texture.h for others) |
6.16 |
uint8 |
quality_level |
Leave 0 for default quality (according to texture-quality-level), 1=fastest, 2=normal, 3=best |
|
uint8 |
format |
Texture format, see texture.h for values. Common values: 12=F_rgba 16=F_rgba8 32=F_srgb_alpha |
|
uint8 |
num_components |
Number of components (eg. 4 for RGBA), MUST match number of components in format |
Only present if texture_type is TT_buffer_texture
|
uint8 |
usage_hint |
|
6.28 |
uint8 |
auto_texture_scale |
Power-of-two texture scaling that will be applied on loading this model, one of: |
0 |
ATS_none |
No scaling happens (requires non-POW2 support in driver) |
1 |
ATS_down |
Scale down to next smaller POW2 size. |
2 |
ATS_up |
Scale up to next larger POW2 size. |
3 |
ATS_pad |
Pad (do not scale) to next larger POW2 size. Requires scaling texture coordinates. |
4 |
ATS_unspecified |
Use the default value. |
|
6.18 |
uint32 |
orig_file_x_size |
Width of the image before scaling. Not sure if you can just leave this zero when loading from disk? |
6.18 |
uint32 |
orig_file_y_size |
Height of the image before scaling. |
6.18 |
bool |
has_simple_ram_image |
If true, there is a lower resolution raw version of this image that can be shown before the full version is loaded from disk. Leave false if in doubt. |
Only present if has_simple_ram_image is true
|
uint32 |
simple_x_size |
Width of simple image |
|
uint32 |
simple_y_size |
Height of simple image |
|
int32 |
simple_image_date_generated |
Height of simple image |
|
uint32 |
|
Number of bytes of raw data that follow |
|
bytearray |
|
|
|
Only present if has_rawdata is true
|
uint32 |
x_size |
|
uint32 |
y_size |
|
uint32 |
z_size |
6.30 |
uint32 |
pad_x_size |
6.30 |
uint32 |
pad_y_size |
6.30 |
uint32 |
pad_z_size |
6.26 |
uint32 |
num_views |
|
uint8 |
component_type |
|
uint8 |
component_width |
6.1 |
uint8 |
ram_image_compression |
6.3 |
uint8 |
num_ram_images |
Repeated for num_ram_images (defaults to 1 before 6.3)
6.1 |
uint32 |
page_size |
|
bytearray |
|
|
|
### TransformState
All nodes must have a TransformState reference, but it is perfectly fine
to create a single TransformState referring to the identity
transformation and refer to that in all nodes that don't have an
explicit transform. Since transform states are immutable in Panda3D,
there are no negative consequences from sharing them between different
nodes.
Transformations can be expressed in various ways. Besides the specially
marked "identity" and "invalid" transforms, there may be componentwise
specification of the transformation, or a matrix can be specified. Both
may be specified, but this is not necessary as Panda3D will calculate
one from the other at request.
|
uint32 |
flags |
This is a complex bitmask, but writers should choose one of the following: |
0x00010005 |
Identity transformation. |
0x00000096 |
Invalid transformation, used for error conditions. |
0x00000338 |
Componentwise transformation, given as pos, quat, scale, shear. |
0x00000c38 |
Componentwise transformation, given as pos, hpr, scale, shear. |
0x00000040 |
Transformation is given as a 4x4 matrix. |
As of 5.2, any of these may be OR-ed with 0x00010000 to indicate that it is a 2-D transformation, although this does not affect the storage size of the components. |
Only present if flags includes 0x00000008
|
stdfloat[3] |
pos |
|
stdfloat[4/3] |
quat/hpr |
|
stdfloat[3] |
scale |
|
stdfloat[3] |
shear |
|
Only present if flags includes 0x00000040
|
stdfloat[16] |
matrix |
|
## Example
This is an annotated hex dump of a simple .bam file.
```
70 62 6a 00 0a 0d The magic code "pbj\0\n\r"
06 00 00 00 A 6-byte datagram follows
06 00 21 00 Version number is 6.33
01 00 Little-endian vertex data, single precision floats
a1 00 00 00 A 161-byte datagram follows
00 BOC_push: open a nesting block, an object follows
cc 01 This object has type index 460, type info follows
09 00 Type name string has 9 characters
4d6f64656c526f6f74 "ModelRoot"
01 This type has one parent type
cb 01 Parent type has index 459, type info follows
09 00 Type name string has 9 characters
4d6f64656c4e6f6465 "ModelNode"
01 This type has one parent type
3c 00 Parent type has index 60
09 00 Type name string has 9 characters
50616e64614e6f6465 "PandaNode"
... rest of type hierarchy ...
01 00 This is object ID 1
05 00 5363656e65 PandaNode::_name (5-character string "Scene")
02 00 PandaNode::_state (reference to object 2)
03 00 PandaNode::_transform (reference to object 3)
04 00 PandaNode::_effects (reference to object 4)
00 00 00 00 PandaNode::_draw_control_mask
ff ff ff ff PandaNode::_draw_show_mask (all visible)
00 00 00 00 PandaNode::_into_collide_mask
00 PandaNode::_bounds_type (0 = BT_default)
00 00 00 00 PandaNode::_tags.size() (no tags)
00 00 PandaNode has 0 parents
02 00 PandaNode has 2 children, which are:
05 00 first child is object ID 5
00 00 00 00 first child has sort 0
06 00 second child is object ID 6
00 00 00 00 second child has sort 0
00 00 PandaNode has 0 stashed children
00 ModelNode::_preserve_transform = PT_none
00 00 ModelNode::_preserve_attributes
82 00 00 00 A 130-byte datagram follows
02 BOC_adjunct: an object follows directly
da 01 This object has type index 474, type info follows
0b 00 Type name string has 11 characters
52656e6465725374617465 "RenderState"
... rest of RenderState type hierarchy ...
... to be continued ...
```
## Changelog
This is a list of revisions that changed the version number of the .bam
format, in chronological order. Click on the dates to be taken to the
associated GitHub revision page.
| | | |
| ---- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------- |
| 2.3 | [2000-11-21](https://github.com/panda3d/panda3d/commit/174bdd8807726dbb3be0440cfbb4631b897adacd) | dual-image textures. |
| 2.4 | [2000-11-28](https://github.com/panda3d/panda3d/commit/0287c81e94ef0a871b8fad598d98be7f33ef1788) | anisotropic texture filtering. |
| 3.0 | [2000-12-08](https://github.com/panda3d/panda3d/commit/d69d3fc470f953b7b47b72b385fe913691c159ab) | change float64's to float32's. |
| 3.1 | [2000-12-15](https://github.com/panda3d/panda3d/commit/ba2608b7b429d0408467bb39051ce3531004bee3) | add FFT-style channel |
| 3.2 | [2001-02-15](https://github.com/panda3d/panda3d/commit/032f773b53e453288fa8c00b807c5e449cc42b24) | add ModelNode::_preserve_transform. |
| 3.3 | [2001-04-11](https://github.com/panda3d/panda3d/commit/e1f0c9a90863410250484993ac0ed4cc5dac1107) | support correctly ordered children. |
| 3.4 | [2001-12-11](https://github.com/panda3d/panda3d/commit/fc6db22bb173173244d3939faf547ab538068276) | transpose quaternions. |
| 3.5 | [2001-12-13](https://github.com/panda3d/panda3d/commit/4a0b5d3d7ea4ffb502a5b777795b6a07568f0fee) | remove obsolete fields from Texture. |
| 3.6 | [2002-05-16](https://github.com/panda3d/panda3d/commit/e46050a69e6929544af360c32912431124fe6c77) | add ImageBuffer::_filename. |
| 3.7 | [2002-05-19](https://github.com/panda3d/panda3d/commit/d4482780b5ae47ecb3bd91a3ea1c18d4371be5b3) | add CharacterJoint::_net_transform_nodes, etc. |
| 4.0 | [2002-04-10](https://github.com/panda3d/panda3d/commit/a23a7572a2682cae2255c52583c2cef45d2eeb9b) | store new scene graph. |
| 4.1 | [2003-04-10](https://github.com/panda3d/panda3d/commit/6e686caf8c0a42dc2d3741ee6f1041df9096d90f) | add CullFaceAttrib::reverse. |
| 4.2 | [2003-04-12](https://github.com/panda3d/panda3d/commit/28743b123bc283e998bd676b6054d6cb62985e98) | add num_components to texture. |
| 4.3 | [2003-04-15](https://github.com/panda3d/panda3d/commit/df2a60cfb09c24ed56e42c0eafd1d7ca759f818e) | add ImageBuffer::_alpha_file_channel. |
| 4.4 | [2003-06-12](https://github.com/panda3d/panda3d/commit/c03d886691380dd05fafdf4745d47659ecb24562) | add PandaNode::set_tag(). |
| 4.5 | [2003-07-09](https://github.com/panda3d/panda3d/commit/f7569695f82a923bf4dae7eb58357d0c93bc66e6) | add rawdata mode to texture |
| 4.6 | [2003-07-22](https://github.com/panda3d/panda3d/commit/344ca11ffd2e7e7f2f7c5cb416df02f0faac526f) | add shear to scene graph and animation data. |
| 4.7 | [2003-11-10](https://github.com/panda3d/panda3d/commit/2536db25f45f9df28dee0366e5f570651772767d) | add CollisionSolid::_effective_normal |
| 4.8 | [2003-11-12](https://github.com/panda3d/panda3d/commit/e1a8ff794c4b2eeede97903044bfecae28ee8103) | add FFTCompressor::reject_compression |
| 4.9 | [2003-12-02](https://github.com/panda3d/panda3d/commit/35f5cd7d67c8d7d85adaaca2a9b2a4dff9fc996d) | change CollisionPolygon internals. |
| 4.10 | [2004-04-23](https://github.com/panda3d/panda3d/commit/dec4cb4bdb9c3ef449a76a0cb291ccd4866c0da7) | make ComputedVertices use uint32's. |
| 4.11 | [2004-07-26](https://github.com/panda3d/panda3d/commit/c7c639797e7abad770f7eff31956d7b8a5d58dc5) | add multitexture pointers. |
| 4.12 | [2004-09-22](https://github.com/panda3d/panda3d/commit/0369f07074e1f21c73937d709c2b991a34b52f66) | add PandaNode::into_collide_mask. |
| 4.13 | [2004-09-24](https://github.com/panda3d/panda3d/commit/d850afd71aaa95abfb8d3521f0abf17a4c8c5207) | store actual LODNode switch distances instead of squares. |
| 4.14 | [2004-11-18](https://github.com/panda3d/panda3d/commit/8747959c7b41c5ef03677f665e707e383184ebed) | differentiate old_hpr from new_hpr in compressed anim channels. |
| 4.15 | [2005-01-16](https://github.com/panda3d/panda3d/commit/d9d30855d014525415de9aad34f0955fecb76b4a) | remove width from GeomLine, etc. |
| 4.16 | [2005-02-24](https://github.com/panda3d/panda3d/commit/ffdbf61985855d4ac855eee214392d49f0f3a77f) | add TextureStage::rgb_scale, etc. |
| 4.17 | [2005-03-03](https://github.com/panda3d/panda3d/commit/87d03ccb34c914fa47258a17a0524f8535d9fc9c) | add 3-d textures, etc. |
| 4.18 | [2005-04-05](https://github.com/panda3d/panda3d/commit/8dd9c1419cb6be8c3453e69c4c4b424ba4b7a4ee) | add RenderModeAttrib::perspective. |
| 4.19 | [2005-04-19](https://github.com/panda3d/panda3d/commit/e0dca3b43bba2a74f97407f28339c0a67704cf29) | add nonindexed qpgeom primitives. |
| 5.0 | [2005-05-06](https://github.com/panda3d/panda3d/commit/bc0d5090900a2314d1eacbd764d5a5f2f1fd3bab) | new Geom implementation. |
| 5.1 | [2005-07-14](https://github.com/panda3d/panda3d/commit/ba139578e0dc7416a31a21bea68fa130c1cef1c0) | add TextureStage::_saved_result. |
| 5.2 | [2005-07-21](https://github.com/panda3d/panda3d/commit/65458d9edd882aa410509b10211da8a91e95d174) | add TransformState::is_2d. |
| 5.3 | [2005-08-25](https://github.com/panda3d/panda3d/commit/1e81e656ab3935547de4c3a4c71b9c6f67e4e3da) | add ModelNode::_preserve_attributes. |
| 5.4 | [2005-09-27](https://github.com/panda3d/panda3d/commit/54655719635ac32c706b8d8fd6412b69a425eb15) | make SequenceNode inherit from AnimInterface. |
| 5.5 | [2005-12-22](https://github.com/panda3d/panda3d/commit/ef0f4859329cdd34ff3d3a673b47abc488ff05cf) | add Texture::_border_color. |
| 5.6 | [2006-01-14](https://github.com/panda3d/panda3d/commit/cf01ef9cd6e70355d64dcc5e68b5bd69bfaac202) | add Material::_name. |
| 6.0 | [2006-02-11](https://github.com/panda3d/panda3d/commit/1d2282a879145b237fcb2d5f6fbf55510df663e6) | factor out PandaNode::CData. |
| 6.1 | [2006-03-12](https://github.com/panda3d/panda3d/commit/e6369ba5a4211ddc1e6cd320f33c75a4d4e1dcb1) | add Texture::_compression. |
| 6.2 | [2006-03-17](https://github.com/panda3d/panda3d/commit/725e82e6f465d0cabc7ec1a3f70f77817f1e2f1e) | add PandaNode::_draw_control_mask. |
| 6.3 | [2006-03-21](https://github.com/panda3d/panda3d/commit/f803ef85ceeaa8247ff72e73a259300ff01c9a63) | add Texture::_ram_images. |
| 6.4 | [2006-07-26](https://github.com/panda3d/panda3d/commit/8e178ae9d605940f1c8b9125cb9f70e5828277c0) | add CharacterJoint::_character. |
| 6.5 | [2006-11-15](https://github.com/panda3d/panda3d/commit/ccec9eb3df572159d03509f14474ea11b2659b64) | add PartBundleNode::_num_bundles. |
| 6.6 | [2007-02-05](https://github.com/panda3d/panda3d/commit/63edecf517525d39c61cfb9aaac3533fab4032ad) | change GeomPrimitive::_num_vertices. |
| 6.7 | [2007-02-15](https://github.com/panda3d/panda3d/commit/e43f4f5c64a3a2eeac38d6954e43ea67af9217fc) | change SliderTable. |
| 6.8 | [2007-05-12](https://github.com/panda3d/panda3d/commit/0329972a41939b40c79ddb681b5a7afb6c6e5ae2) | change GeomVertexArrayData::_data. |
| 6.9 | [2007-05-15](https://github.com/panda3d/panda3d/commit/7e08d7b759a5ef23a817c90cbce8bc9ab664af54) | add PlaneNode::_clip_effect. |
| 6.10 | [2007-06-19](https://github.com/panda3d/panda3d/commit/823bd7a56c76f85ba9bf5b29524f3e23344e7a4b) | properly write PartBundles. |
| 6.11 | [2007-06-20](https://github.com/panda3d/panda3d/commit/4bce07faaa667c35cf5604b9a6d236baf9528467) | write frozen joints to PartGroups. |
| 6.12 | [2007-07-03](https://github.com/panda3d/panda3d/commit/81ae62f553607abd1e9b85e7dcd8e8135c3b3b98) | rework control/frozen joints more. |
| 6.13 | [2007-08-15](https://github.com/panda3d/panda3d/commit/1ccd464d81f9d4b982cc9ac9b43d0ab3235f284b) | reverse CollisionPolygon vertices. |
| 6.14 | [2007-12-19](https://github.com/panda3d/panda3d/commit/775466b4bd74c15e09f17b67b19cba2840091757) | change default ColorAttrib. |
| 6.15 | [2008-04-09](https://github.com/panda3d/panda3d/commit/a667e91dce10bacfabdf59ecdc9bc0457b97de17) | add TextureAttrib::_implicit_sort. |
| 6.16 | [2008-05-13](https://github.com/panda3d/panda3d/commit/acb0faae46e383d4a7a9dabd1062d6d91256fe68) | add Texture::_quality_level. |
| 6.17 | [2008-08-06](https://github.com/panda3d/panda3d/commit/35baf6a2eeee00403b40a96ad6a230bfcae65028) | add PartBundle::_anim_preload. |
| 6.18 | [2008-08-14](https://github.com/panda3d/panda3d/commit/617a769ef760f7564bd3d64ddfbe6629a55c748c) | add Texture::_simple_ram_image. |
| | [2008-08-14](https://github.com/panda3d/panda3d/commit/b07dbcc262263b1bb74288d47d3d95ae7e1994bb) | remove support for pre-6.14 bams |
| 6.19 | [2008-08-14](https://github.com/panda3d/panda3d/commit/ddbad778518638a4aae0b6357c578789f0931213) | add PandaNode::_bounds_type. |
| 6.20 | [2009-04-21](https://github.com/panda3d/panda3d/commit/aee550231c7b5b5b234efc625b72d71b5ca7b58c) | add MovingPartBase::_forced_channel. |
| 6.21 | [2008-02-26](https://github.com/panda3d/panda3d/commit/aefe3d35c2f2fbcf67a46ed92e5c0a409bfc1172) | add BamEnums::BamObjectCode. |
| 6.22 | [2009-07-31](https://github.com/panda3d/panda3d/commit/8db00b4f74e0edae94c2a8cda91c4e126e48033c) | add UvScrollNode R speed. |
| 6.23 | [2010-05-04](https://github.com/panda3d/panda3d/commit/9d62ca9f98b29995f770fbfd083b5760ef52e523) | add internal TextureAttrib overrides. |
| 6.24 | [2010-05-04](https://github.com/panda3d/panda3d/commit/91e6231a3c948d3e011512bc81ed778f054a2f54) | add internal TexMatrixAttrib overrides. |
| 6.25 | [2011-06-22](https://github.com/panda3d/panda3d/commit/285d70c29e0d16f7bf77d51889e5116f0b0b896e) | add support for caching movie files. |
| 6.26 | [2011-08-05](https://github.com/panda3d/panda3d/commit/6872488839b5c979f4926bb258b17fa651a83bda) | add multiview (stereo) Textures. |
| 6.27 | [2011-10-09](https://github.com/panda3d/panda3d/commit/501470169f0513d1075427eb0069a6aeea30ef5d) | add stdfloat_double. |
| 6.28 | [2011-11-28](https://github.com/panda3d/panda3d/commit/3d89cef5443266eedb16ee23a72124ea8cad6ae5) | add Texture::_auto_texture_scale. |
| 6.29 | [2011-12-17](https://github.com/panda3d/panda3d/commit/a4728957da7086a3025740335807918e4173808a) | add GeomVertexColumn::_column_alignment. |
| 6.30 | [2012-01-22](https://github.com/panda3d/panda3d/commit/deb8a56b8acd7b034834aeaf79d298ed67921545) | add Texture::_pad_*_size. |
| 6.31 | [2012-02-16](https://github.com/panda3d/panda3d/commit/3a75ebde9a805648f0d581ceb8f032ca5db5448c) | add DepthOffsetAttrib::_min_value, _max_value |
| 6.32 | [2012-06-11](https://github.com/panda3d/panda3d/commit/5ba7076808908cd2ff676e032beb1d8f20acf1e8) | add Texture::_has_read_mipmaps. |
| 6.33 | [2013-08-17](https://github.com/panda3d/panda3d/commit/a585faa807765c5b297533cb45020cb93d636c56) | add UvScrollNode::_w_speed. |
| 6.34 | [2014-09-16](https://github.com/panda3d/panda3d/commit/8b7217b4f9d80284a3b4e9fcb15d34c24add11bd) | add ScissorAttrib::_off. |
| 6.35 | [2014-12-03](https://github.com/panda3d/panda3d/commit/0473fa7eadece14d046be963a7f505e91ea6b8ed) | change StencilAttrib. |
| 6.36 | [2014-12-09](https://github.com/panda3d/panda3d/commit/95d85819b032a26b2eb1f06798f746235607cca3) | add samplers and lod settings. |
| 6.37 | [2015-01-22](https://github.com/panda3d/panda3d/commit/77c9e6cf6c4bb52d5d39777f3e47c94c369f8b0c) | add GeomVertexArrayFormat::_divisor. |
| 6.38 | [2015-04-15](https://github.com/panda3d/panda3d/commit/38ac0401ce19ff326ee54f451782efef2c508d07) | add various Bullet classes. |
| 6.39 | [2016-01-09](https://github.com/panda3d/panda3d/commit/3393454582a6330dbc3df775d29e94221198863a) | change lights and materials. |
| 6.40 | [2016-01-11](https://github.com/panda3d/panda3d/commit/41fad59ae8c32eb23c1ef848f64f803a0d54eec9) | make NodePaths writable. |
| 6.41 | [2016-03-02](https://github.com/panda3d/panda3d/commit/2971915618053b159069b5dcb28ed55ac826f1a3) | change LensNode, Lens and Camera. |
| 6.42 | [2016-04-08](https://github.com/panda3d/panda3d/commit/f0cd1ce3158e52c4b3b8ed338ec510c9d2a33398) | expand ColorBlendAttrib. |
| 6.43 | [2018-12-06](https://github.com/panda3d/panda3d/commit/89236ac1360e5f0249d425e61d537deef40e71c3) | change BillboardEffect and CompassEffect. |
| 6.44 | [2018-12-23](https://github.com/panda3d/panda3d/commit/bd6ef2b0ea2832ff1095f9e41b3137452f0619f4) | rename CollisionTube to CollisionCapsule. |
| 6.45 | [2020-03-18](https://github.com/panda3d/panda3d/commit/e138096578c5cd7a7f509dfb0c2dbc30c369a7dc) | add Texture::_clear_color. |