It is a little more complicated than as explained by Wardrums. As of Blender 2.77 my experiments yielded the following results:
b'BPHYSICS'
flavor : i32 #=1 for point cache
count : i32
data_type_flags : i32 #I think this relates to BPHYS_DATA_* in DNA_object_force_h
for i in range(count):
index : i32
location : i32[3]
velocity : i32[3]
For my particular sample file the data_type_flags==7 and the table only contained the index, location, and velocity. This corresponds to (1<<BPHYS_DATA_INDEX)|(1<<BPHYS_DATA_LOCATION)|(1<<BPHYS_DATA_VELOCITY)
. I suspect that particle systems that use an object group for rendering instead of a halo will have PHYS_DATA_ROTATION, and other particle system features will bring in other flags requiring more of the columns that Wardrums documented. Likewise other cache formats (cloth, smoke, rigid body) will make use of columns not used by particles.
One other thing is that the count
and data_type_flags
are read by pid->read_header
which as far as I can tell is only ptcache_basic_header_read
but there might be a mode where it is a different function, and things might change in the future.
I have also noticed that the very first file (_000000_00.bphys) has only time information (data_type_flags=0x40) and in my file the rows looked like
{'times': (1.0, 51.0, 50.0)}
{'times': (1.1990000009536743, 51.19900131225586, 50.0)}
{'times': (1.3980000019073486, 51.39799880981445, 50.0)}
which I assume to be (start,end,lifetime) numbers as frames. This file may or may not be important if you're attempting to synthesize your own point cache files from scratch.
Just for completeness, here is an early draft of http://web.purplefrog.com/~thoth/blender/python-cookbook/dump-point-cache.html I used to dump my particle cache:
import struct
def dump_one_file(fname):
f = open(fname, "rb")
magic = f.read(8)
if magic != b'BPHYSICS':
raise Exception("not a blender physics cache")
flavor = f.read(12)
(flavor,count,something) = struct.unpack("iii", flavor)
print( "%d\t%d\t%d"%(flavor,count,something))
if flavor==1: # point cache
rec_len = 28
while True:
chunk = f.read(rec_len)
if chunk is None or len(chunk)==0:
break
if len(chunk) != rec_len:
raise Exception("short read (%d<%d)"%(len(chunk), rec_len))
all = struct.unpack("i fff fff ", chunk)
print( "%d\t<%f,%f,%f>\t<%f,%f,%f>"%all)
dump_one_file("/var/tmp/blendcache_particle/pants_000238_00.bphys")