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