Skip to content

Instantly share code, notes, and snippets.

@loki42
Last active August 29, 2015 13:58
Show Gist options
  • Save loki42/10229793 to your computer and use it in GitHub Desktop.
Save loki42/10229793 to your computer and use it in GitHub Desktop.
Simple generator for CRYENGINE 3.5 binary vegetation files with Python
import sys, uuid
import math
from struct import *
file_for_import = sys.argv[1]
layer = sys.argv[2]
y_offset = float(sys.argv[3])
x_offset = float(sys.argv[4])
z_offset = float(sys.argv[5])
scale_multiplier = 1.0
tree_prefabs = {'Kapok1':["objects/foliage/trees/kapok/Kapok1.cgf", 1.0]
#lower case keys
tree_prefabs = {i.lower():j for i,j in tree_prefabs.items()}
def generate_trees():
tree_key_list = sorted(list(tree_prefabs.keys()))
# this is xml that defines each type of tree
template = ' <Object Size="1" SizeVar="0" RandomRotation="0" AlignToTerrain="0" UseTerrainColor="0" AllowIndoor="0" Bending="0" Hideable="0" PlayerHideable="0" GrowOnVoxels="0" GrowOnBrushes="0" GrowOnTerrain="1" AutoMerged="0" Stiffness="0.5" Damping="2.5" Variance="0.6" AirResistance="1" Pickable="0" AIRadius="-1" Brightness="1" Density="1" ElevationMin="113" ElevationMax="4096" SlopeMin="0" SlopeMax="255" CastShadow="0" CastShadowMinSpec="8" RecvShadow="0" AlphaBlend="0" SpriteDistRatio="1" LodDistRatio="1" MaxViewDistRatio="1" Material="" UseSprites="1" MinSpec="0" Frozen="0" Layer_Wet="0" Object="%(prefab)s" Id="%(tree_i)s" FileName="%(prefab)s" GUID="{%(uuid)s}" Hidden="0" Index="%(tree_i)s" Category="Default"/>'
with open('VegetationMap.dat', 'wb') as out_file:
tree_info = """<VegetationMap Version="2">
<Objects>
"""+'\n'.join([template % {'prefab':tree_prefabs[v][0].lower(), 'tree_i':i, 'uuid':str(uuid.uuid1()).upper()} for i,v in enumerate(tree_key_list)])+ """
</Objects>
</VegetationMap>"""
# so we fill out the xml header with the info for each type of tree, and generate UUID's for each of the tree classes
out_str = tree_info.encode('utf-8')
print("out string is ", len(out_str))
# now we put this header on it, look at the docs for pack in python docs, and run it in the interpreter
header = b'\xff'+pack('=H', len(out_str)+1)# the size of the list of available trees, as an unsigned 16 bit int
out_file.write(header) # header goes first
out_file.write(out_str) # then the xml
boundry = b'\x0A\x01\x00\x00\x00\x18\x56\x65\x67\x65\x74\x61\x74\x69\x6F\x6E\x49\x6E\x73\x74\x61\x6E\x63\x65\x73\x41\x72\x72\x61\x79'
out_file.write(boundry) # write the boundry
num_trees = 0
tree_encoded_data = b''
for line in open(file_for_import, 'r'):
line = line.replace("(","").replace(")","").strip() # this is just processing my input format
name, position, rotation, scale = line.split(":")
x, y, z = position.split(', ')
y = float(y) + y_offset
x = float(x) + x_offset
z = float(z) + z_offset
scale = [(float(a) * scale_multiplier) for a in scale.split(', ')]
if name.lower() in tree_prefabs:
num_trees = num_trees + 1
# back to the exciting stuff
tree_encoded_data = tree_encoded_data + pack('=fffffBffB', 0.0, x, y, z, scale[0], tree_key_list.index(name.lower()), 3.57331e-043, 0.0, 0)
# write each tree in the correct encoding, the arg to pack specifies the binary output formating, look it up to see how many bits for each section
# first write the header for this section, that says how many trees (not tree classes) there are
out_file.write(pack('=II', num_trees * 30, num_trees * 30)) # same twice, not sure why
# write out the tree data
out_file.write(tree_encoded_data)
# then write the footer
footer = b'\x00\x00\x00\x00'
out_file.write(footer)
generate_trees()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment