Skip to content

Instantly share code, notes, and snippets.

@kdrnic
Created April 18, 2020 23:38
Show Gist options
  • Save kdrnic/b62c7bb2007deab2f25c3cd214db7421 to your computer and use it in GitHub Desktop.
Save kdrnic/b62c7bb2007deab2f25c3cd214db7421 to your computer and use it in GitHub Desktop.
"""
TurboBSP Power 97 2.0 lightmap baker and map exporter script
Lightmap bake script
Objectives
----------
-Source is regular Blender file, containing a level
-Level geometry must be in an object called "level"
-"lightmap" object if present will be deleted
-A new will then be created, cloned from "level"
-At the end, level is exported to KOBJ format
"""
import bpy
import os
C = bpy.context
D = bpy.data
scene = C.scene
Ops = bpy.ops
filepath = D.filepath
filename = bpy.path.basename(filepath)
bake_margin = int(os.getenv("bake_margin", "2"))
#filedir = os.path.dirname(filepath)
filedir = os.getcwd()
texdir = os.getenv("texdir", os.path.join(filedir, "lmaps"))
tex_res = int(os.getenv("tex_res", "256"))
number_of_samples = int(os.getenv("number_of_samples", "20"))
# Set baking options
scene.cycles.bake_type = "COMBINED"
scene.render.bake_margin = bake_margin
scene.render.use_bake_normalize = True
# Change samples to avoid grainy light map
scene.cycles.samples = number_of_samples
bpy.context.scene.render.engine = 'CYCLES'
#Attempts to improve perf
bpy.context.scene.cycles.device = 'GPU'
scene.cycles.max_bounces = 4
scene.cycles.min_bounces = 0
scene.render.bake.use_pass_subsurface = False
scene.render.bake.use_pass_glossy = False
scene.cycles.use_denoising = True
#Force object mode
Ops.object.mode_set(mode='OBJECT', toggle=False)
#If one lightmap obj already exists, delete the fucker
if "lightmap" in D.objects:
lmobj = D.objects["lightmap"]
lmobj.user_clear()
D.objects.remove(lmobj, do_unlink=True)
#Create new object from level object
lvlobj = D.objects["level"]
lmobj = lvlobj.copy()
lmobj.data = lvlobj.data.copy()
lmobj.name = "lightmap"
lmobj.data.name = "lightmap"
scene.objects.link(lmobj)
#Hide objects not contributing to lightmap
for i,obj in enumerate(scene.objects):
if obj.type != 'LAMP':
if obj != lmobj:
if not obj.name.startswith("mdl"):
obj.hide_render = True
# Select object and make active
Ops.object.select_all(action='DESELECT')
scene.objects.active = lmobj
lmobj.select = True
#Remove all object material slots
for x in lmobj.material_slots:
lmobj.active_material_index = 0
Ops.object.material_slot_remove({'object': lmobj})
# Create material if not exist
if "lightmapmat" in D.materials:
bpy.data.materials.remove(D.materials["lightmapmat"])
D.materials.new(name="lightmapmat")
mat = D.materials["lightmapmat"]
#Force create new image with correct size
if "lightmapimg" in D.images:
D.images.remove(D.images["lightmapimg"])
D.images.new(name = "lightmapimg", width=int(tex_res), height=int(tex_res))
img = D.images["lightmapimg"]
#Add image texture node
mat.use_nodes = True
nodes = mat.node_tree.nodes
node = nodes.new('ShaderNodeTexImage')
node.image = img
#Add material to first new slot
lmobj.data.materials.append(mat)
# Select object and make active
Ops.object.select_all(action='DESELECT')
scene.objects.active = lmobj
lmobj.select = True
#Set edit mode
Ops.object.mode_set(mode='EDIT', toggle=False)
#Select all faces
Ops.mesh.select_mode(type="FACE")
Ops.mesh.select_all(action='SELECT')
#Assign our material
Ops.object.material_slot_assign()
#Do the UVing
Ops.uv.lightmap_pack(PREF_CONTEXT='SEL_FACES', PREF_PACK_IN_ONE=True, PREF_NEW_UVLAYER=False, PREF_APPLY_IMAGE=False, PREF_IMG_PX_SIZE=int(tex_res), PREF_BOX_DIV=12, PREF_MARGIN_DIV=(float(bake_margin) * 100.0)/float(tex_res))
# Now do the baking
Ops.object.bake(type="COMBINED")
# Unselect the object
lmobj.select = False
# Save the image
img.save_render(os.path.join(texdir, (filename.rsplit( ".", 1 )[ 0 ]) + ".png"))
# Save .blend
#bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)
# Export KOBJ
bpy.ops.export_scene.kobj(filepath = os.path.join(filedir, (filename.rsplit( ".", 1 )[ 0 ]) + ".obj"), path_mode = 'STRIP')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment