Krakatoa
RSS< Twitter< etc
PRT File Format

PRT File Format

NOTE: The PRT v1.0 format is documented here for legacy purposes. New development should target the v1.1 spec found here.

The Krakatoa Particle File Format (.PRT) format is the standard file format used in Krakatoa, which best supports all the options and capabilities that Krakatoa has to offer. The file format allows for the use of an arbitrary number of channels, each with a customizable type and name.

The file format is designed so the header is uncompressed while the particle data is compressed. This provides the ability to efficiently write a PRT file without knowing ahead of time how many particles will be written, by seeking back into the header and updating it with the correct particle count once all the particles have been written. When doing this, it is recommended that the value -1 be written to the particle count initially, so that Krakatoa and other programs can detect it as an error condition when loading the file.

Channel names are restricted, and should start with a letter or '_' character, and contain only letters, numbers and '_'. This restriction is imposed to provide for the possibility of implementing scripting support in Krakatoa and other systems where the channel names are directly used in the language to access those channels. Consider, for example, what a Krakatoa shading language would be like. Channel names are case sensitive.

For Krakatoa to work with a PRT file, the file must at minimum contain a Position channel which contains 3 values of a floating point type. See Krakatoa Particle Channels for information about what channels Krakatoa uses.

Format Specification

The PRT file format consists of:

  • A header for general file information.
  • A channel definitions section, detailing the channel-wise data included in each particle.
  • A block of binary data for the particles. This is compressed using zlib's deflate method.

All data is in little-endian byte order.

PRT File Header

(56 bytes)

(8 bytes)  Magic number that indicates the PRT file format. The number is defined by the following sequence of ASCII characters: 
           {192, 'P', 'R', 'T', '\r', '\n', 26, '\n'}
(4 bytes)  A 32 bit int indicating the length of the header (Has value 56).
(32 bytes) A human readable signature null-terminated string describing the file, currently "Extensible Particle Format".
(4 bytes)  A 32 bit int indicating version (Has value 1).
(8 bytes)  A 64 bit int indicating particle count.

Reserved Bytes

(4 bytes)

(4 bytes) A 32 bit int, should be set to the value 4.

Channels Definition Section

(Variable Length)

Header (8 bytes)

(4 bytes)  A 32 bit int indicating the number of channels.
(4 bytes)  A 32 bit int indicating the length of one channel definition structure (Has value 44).

Channel definitions (44 bytes each)

(32 bytes) A null-terminated string indicating the channel name.  Must match the regex "[a-zA-Z_][0-9a-zA-Z_]*".
(4 bytes)  A 32 bit int indicating channel data type.  Supported channel data types are indicated in the table below.
(4 bytes)  A 32 bit int indicating channel arity (number of data values that each particle has for this channel).
(4 bytes)  A 32 bit int indicating channel offset, relative to the start of the particle.
Data Type Integer Value
int16 0
int32 1
int64 2
float16 3
float32 4
float64 5
uint16 6
uint32 7
uint64 8
int8 9
uint8 10

Particle Data

(Variable Size)

The particle data is compressed using a zlib z_streamp object, with the basic zlib deflate API. In Krakatoa, this is implemented with the deflateInit, deflate, and deflateEnd functions for compression, and the inflateInit, inflate, and inflateEnd functions for decompression.

The particles are byte-packed one after another, in the layout specified by the channels definition section.

The float16 data type is the same as the half data type in OpenEXR. The most convenient way to work with them is using the half library component from OpenEXR.

Example

Here's an example PRT file saved from Krakatoa using the vertices from a box. It has 8 particles, and two channels "Position" and "Velocity".

; Magic number: {192, 'P', 'R', 'T', '\r', '\n', 26, '\n'}
000000 c0 50 52 54 0d 0a 1a 0a
; Header length: 56
000008 38 00 00 00
; Identification null-terminated string: "Extensible Particle Format"
00000c 45 78 74 65 6e 73 69 62 6c 65 20 50 61 72 74 69
00001c 63 6c 65 20 46 6f 72 6d 61 74 00 00 00 00 00 00
; Version number: 1
00002c 01 00 00 00
; Particle count: 8
000030 08 00 00 00 00 00 00 00

; Reserved 32-bit value: 4
000038 04 00 00 00

; Number of channels: 2
00003c 02 00 00 00
; Channel definition entry length: 44
000040 2c 00 00 00

; Name of channel 0: "Position"
000044 50 6f 73 69 74 69 6f 6e 00 00 00 00 00 00 00 00
000054 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; Data type of channel 0: float32
000064 04 00 00 00
; Arity of channel 0: 3
000068 03 00 00 00
; Data offset of channel 0: 0
00006c 00 00 00 00

; Name of channel 1: "Velocity"
000070 56 65 6c 6f 63 69 74 79 00 00 00 00 00 00 00 00
000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; Data type of channel 1: float32
000090 04 00 00 00
; Arity of channel 1: 3
000094 03 00 00 00
; Data offset of channel 1: 12
000098 0c 00 00 00

; Zlib compressed binary particle data
00009c 78 9c e3 d8 3e e3 60 c1 f9 15 07 19 d0 c0 05 ad
0000ac 33 8e d8 c4 39 80 ea 27 78 55 3b 62 53 8f 4d 9c
0000bc 03 6a 7e 63 c1 7f 47 74 f5 d8 c4 61 e6 63 53 8f
0000cc 4d 1c 00 cb 5d 2a 39

The compressed binary particle data will consist of 24 bytes per particle, 12 for the position triplet and 12 for the velocity triplet:

[float32][float32][float32][float32][float32][float32][float32][float32][float32][float32][float32][float32]...
|_________________________||_________________________||_________________________||_________________________|
         position                    velocity                  position                    velocity
|____________________________________________________||____________________________________________________|
                      particle 1                                            particle 2

As mentioned above, it is recommended that when the particle count isn't known ahead of time, the value -1 be written to the particle count initially. This way, Krakatoa and other programs can detect it as an error condition of an incomplete file when loading the file if the count value didn't get fixed up to the correct value on completion. Once the per particle information has been packed into the file, the particle count in the header can then be updated to the true value.

SEE ALSO