mirror of https://github.com/H-uru/korman.git
Browse Source
Still lots of considerations: - Need to make faux lightgroups to avoid baking Plasma RT lights - Still need to bake vertex colors - Still need to export Plasma RT lights (D'oh!) But, this is definitely a step in the right direction!pull/6/head
Adam Johnson
10 years ago
10 changed files with 296 additions and 13 deletions
@ -0,0 +1,29 @@ |
|||||||
|
# This file is part of Korman. |
||||||
|
# |
||||||
|
# Korman is free software: you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation, either version 3 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# Korman is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
class GoodNeighbor: |
||||||
|
"""Leave Things the Way You Found Them! (TM)""" |
||||||
|
|
||||||
|
def __enter__(self): |
||||||
|
self._tracking = {} |
||||||
|
return self |
||||||
|
|
||||||
|
def track(self, cls, attr, value): |
||||||
|
self._tracking[(cls, attr)] = getattr(cls, attr) |
||||||
|
setattr(cls, attr, value) |
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback): |
||||||
|
for (cls, attr), value in self._tracking.items(): |
||||||
|
setattr(cls, attr, value) |
@ -0,0 +1,106 @@ |
|||||||
|
# This file is part of Korman. |
||||||
|
# |
||||||
|
# Korman is free software: you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation, either version 3 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# Korman is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
import bpy |
||||||
|
from ..helpers import GoodNeighbor |
||||||
|
|
||||||
|
class _LightmapOperator: |
||||||
|
@classmethod |
||||||
|
def poll(cls, context): |
||||||
|
if context.object is not None: |
||||||
|
return context.scene.render.engine == "PLASMA_GAME" |
||||||
|
|
||||||
|
|
||||||
|
class LightmapAutobakeOperator(_LightmapOperator, bpy.types.Operator): |
||||||
|
bl_idname = "object.plasma_lightmap_autobake" |
||||||
|
bl_label = "Bake Lightmap" |
||||||
|
bl_options = {"INTERNAL"} |
||||||
|
|
||||||
|
def execute(self, context): |
||||||
|
with GoodNeighbor() as toggle: |
||||||
|
# We need to ensure that we bake onto the "BlahObject_LIGHTMAPGEN" image |
||||||
|
obj = context.active_object |
||||||
|
data_images = bpy.data.images |
||||||
|
im_name = "{}_LIGHTMAPGEN".format(obj.name) |
||||||
|
size = obj.plasma_modifiers.lightmap.resolution |
||||||
|
|
||||||
|
im = data_images.get(im_name) |
||||||
|
if im is None: |
||||||
|
im = data_images.new(im_name, width=size, height=size) |
||||||
|
elif im.size != (size, size): |
||||||
|
# Force delete and recreate the image because the size is out of date |
||||||
|
im.user_clear() |
||||||
|
data_images.remove(im) |
||||||
|
im = data_images.new(im_name, width=size, height=size) |
||||||
|
|
||||||
|
# This just wraps Blender's internal lightmap UV whatchacallit... |
||||||
|
# We want to ensure that we use the UV Layer "LIGHTMAPGEN" and fetch the size from |
||||||
|
# the lightmap modifier. What fun... |
||||||
|
mesh = context.active_object.data |
||||||
|
mesh.update() |
||||||
|
|
||||||
|
# Search for LIGHTMAPGEN |
||||||
|
for uvtex in mesh.uv_textures: |
||||||
|
if uvtex.name == "LIGHTMAPGEN": |
||||||
|
toggle.track(mesh.uv_textures, "active", uvtex) |
||||||
|
break |
||||||
|
else: |
||||||
|
# Gotta make it |
||||||
|
uvtex = mesh.uv_textures.new("LIGHTMAPGEN") |
||||||
|
toggle.track(mesh.uv_textures, "active", uvtex) |
||||||
|
|
||||||
|
# Now, enter edit mode on this mesh and unwrap. |
||||||
|
bpy.ops.object.mode_set(mode="EDIT") |
||||||
|
bpy.ops.mesh.select_all(action="SELECT") |
||||||
|
bpy.ops.uv.lightmap_pack(PREF_CONTEXT="ALL_FACES", PREF_IMG_PX_SIZE=size) |
||||||
|
bpy.ops.object.mode_set(mode="OBJECT") |
||||||
|
|
||||||
|
# Associate the image with all the new UVs |
||||||
|
for i in mesh.uv_textures.active.data: |
||||||
|
i.image = im |
||||||
|
|
||||||
|
# Bake settings |
||||||
|
render = context.scene.render |
||||||
|
toggle.track(render, "bake_type", "FULL") |
||||||
|
toggle.track(render, "use_bake_to_vertex_color", False) |
||||||
|
|
||||||
|
for mat in obj.data.materials: |
||||||
|
for tex in mat.texture_slots: |
||||||
|
if tex is not None and tex.use: |
||||||
|
toggle.track(tex, "use", False) |
||||||
|
|
||||||
|
# Now, we *finally* bake the lightmap... |
||||||
|
# FIXME: Don't bake Plasma RT lights |
||||||
|
bpy.ops.object.bake_image() |
||||||
|
|
||||||
|
# Done! |
||||||
|
return {"FINISHED"} |
||||||
|
|
||||||
|
|
||||||
|
class LightmapAutobakePreviewOperator(_LightmapOperator, bpy.types.Operator): |
||||||
|
bl_idname = "object.plasma_lightmap_preview" |
||||||
|
bl_label = "Preview Lightmap" |
||||||
|
bl_options = {"INTERNAL"} |
||||||
|
|
||||||
|
def execute(self, context): |
||||||
|
bpy.ops.object.plasma_lightmap_autobake() |
||||||
|
|
||||||
|
tex = bpy.data.textures.get("LIGHTMAPGEN_PREVIEW") |
||||||
|
if tex is None: |
||||||
|
tex = bpy.data.textures.new("LIGHTMAPGEN_PREVIEW", "IMAGE") |
||||||
|
tex.extension = "CLIP" |
||||||
|
tex.image = bpy.data.images["{}_LIGHTMAPGEN".format(context.active_object.name)] |
||||||
|
|
||||||
|
return {"FINISHED"} |
@ -0,0 +1,82 @@ |
|||||||
|
# This file is part of Korman. |
||||||
|
# |
||||||
|
# Korman is free software: you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation, either version 3 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# Korman is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
|
||||||
|
import bpy |
||||||
|
from bpy.props import * |
||||||
|
from PyHSPlasma import * |
||||||
|
|
||||||
|
from .base import PlasmaModifierProperties |
||||||
|
|
||||||
|
class PlasmaLightMapGen(PlasmaModifierProperties): |
||||||
|
pl_id = "lightmap" |
||||||
|
|
||||||
|
bl_category = "Render" |
||||||
|
bl_label = "Lightmap" |
||||||
|
bl_description = "Auto-Bake Lightmap" |
||||||
|
|
||||||
|
quality = EnumProperty(name="Quality", |
||||||
|
description="Resolution of lightmap", |
||||||
|
items=[ |
||||||
|
("128", "128px", "128x128 pixels"), |
||||||
|
("256", "256px", "256x256 pixels"), |
||||||
|
("512", "512px", "512x512 pixels"), |
||||||
|
("1024", "1024px", "1024x1024 pixels"), |
||||||
|
]) |
||||||
|
|
||||||
|
def created(self, obj): |
||||||
|
self.display_name = "{}_LIGHTMAPGEN".format(obj.name) |
||||||
|
|
||||||
|
def export(self, exporter, bo, so): |
||||||
|
mat_mgr = exporter.mesh.material |
||||||
|
materials = mat_mgr.get_materials(bo) |
||||||
|
lightmap_im = bpy.data.images.get("{}_LIGHTMAPGEN".format(bo.name)) |
||||||
|
|
||||||
|
# Find the stupid UVTex |
||||||
|
uvw_src = 0 |
||||||
|
for i, uvtex in enumerate(bo.data.tessface_uv_textures): |
||||||
|
if uvtex.name == "LIGHTMAPGEN": |
||||||
|
uvw_src = i |
||||||
|
break |
||||||
|
else: |
||||||
|
# TODO: raise exception |
||||||
|
pass |
||||||
|
|
||||||
|
for matKey in materials: |
||||||
|
layer = exporter.mgr.add_object(plLayer, name="{}_LIGHTMAPGEN".format(matKey.name), so=so) |
||||||
|
layer.UVWSrc = uvw_src |
||||||
|
|
||||||
|
# Colors science'd from PRPs |
||||||
|
layer.ambient = hsColorRGBA(1.0, 1.0, 1.0) |
||||||
|
layer.preshade = hsColorRGBA(0.5, 0.5, 0.5) |
||||||
|
layer.runtime = hsColorRGBA(0.5, 0.5, 0.5) |
||||||
|
|
||||||
|
# GMatState |
||||||
|
gstate = layer.state |
||||||
|
gstate.blendFlags |= hsGMatState.kBlendMult |
||||||
|
gstate.clampFlags |= (hsGMatState.kClampTextureU | hsGMatState.kClampTextureV) |
||||||
|
gstate.ZFlags |= hsGMatState.kZNoZWrite |
||||||
|
gstate.miscFlags |= hsGMatState.kMiscLightMap |
||||||
|
|
||||||
|
mat = matKey.object |
||||||
|
mat.compFlags |= hsGMaterial.kCompIsLightMapped |
||||||
|
mat.addPiggyBack(layer.key) |
||||||
|
|
||||||
|
# Mmm... cheating |
||||||
|
mat_mgr.export_prepared_layer(layer, lightmap_im) |
||||||
|
|
||||||
|
@property |
||||||
|
def resolution(self): |
||||||
|
return int(self.quality) |
@ -0,0 +1,31 @@ |
|||||||
|
# This file is part of Korman. |
||||||
|
# |
||||||
|
# Korman is free software: you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation, either version 3 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# Korman is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
import bpy |
||||||
|
|
||||||
|
def lightmap(modifier, layout, context): |
||||||
|
col = layout.column(align=True) |
||||||
|
col.row(align=True).prop(modifier, "quality", expand=True) |
||||||
|
col.operator("object.plasma_lightmap_preview", "Preview Lightmap", icon="RENDER_STILL") |
||||||
|
|
||||||
|
# Kind of clever stuff to show the user a preview... |
||||||
|
# We can't show images, so we make a hidden ImageTexture called LIGHTMAPGEN_PREVIEW. We check |
||||||
|
# the backing image name to see if it's for this lightmap. If so, you have a preview. If not, |
||||||
|
# well... It was nice knowing you! |
||||||
|
tex = bpy.data.textures.get("LIGHTMAPGEN_PREVIEW") |
||||||
|
if tex is not None: |
||||||
|
im_name = "{}_LIGHTMAPGEN".format(context.active_object.name) |
||||||
|
if tex.image.name == im_name: |
||||||
|
layout.template_preview(tex, show_buttons=False) |
Loading…
Reference in new issue