mirror of
https://github.com/H-uru/korman.git
synced 2025-07-14 22:36:52 +00:00
Implement crappy vertex color light baking...
This should make the average age look a little bit better. I hope... If you want to get rid of this crappy lighting, create a vertex color layer. Or, better yet, add a stupid lightmap modifier!
This commit is contained in:
@ -24,6 +24,8 @@ from . import utils
|
|||||||
_MAX_VERTS_PER_SPAN = 0xFFFF
|
_MAX_VERTS_PER_SPAN = 0xFFFF
|
||||||
_WARN_VERTS_PER_SPAN = 0x8000
|
_WARN_VERTS_PER_SPAN = 0x8000
|
||||||
|
|
||||||
|
_VERTEX_COLOR_LAYERS = {"col", "color", "colour"}
|
||||||
|
|
||||||
class _RenderLevel:
|
class _RenderLevel:
|
||||||
MAJOR_OPAQUE = 0
|
MAJOR_OPAQUE = 0
|
||||||
MAJOR_FRAMEBUF = 1
|
MAJOR_FRAMEBUF = 1
|
||||||
@ -148,6 +150,17 @@ class MeshConverter:
|
|||||||
})
|
})
|
||||||
geodata = [_geodatacls() for i in mesh.materials]
|
geodata = [_geodatacls() for i in mesh.materials]
|
||||||
|
|
||||||
|
# Locate relevant vertex color layers now...
|
||||||
|
color, alpha = None, None
|
||||||
|
for vcol_layer in mesh.tessface_vertex_colors:
|
||||||
|
name = vcol_layer.name.lower()
|
||||||
|
if name in _VERTEX_COLOR_LAYERS:
|
||||||
|
color = vcol_layer.data
|
||||||
|
elif name == "autocolor" and color is None:
|
||||||
|
color = vcol_layer.data
|
||||||
|
elif name == "alpha":
|
||||||
|
alpha = vcol_layer.data
|
||||||
|
|
||||||
# Convert Blender faces into things we can stuff into libHSPlasma
|
# Convert Blender faces into things we can stuff into libHSPlasma
|
||||||
for i, tessface in enumerate(mesh.tessfaces):
|
for i, tessface in enumerate(mesh.tessfaces):
|
||||||
data = geodata[tessface.material_index]
|
data = geodata[tessface.material_index]
|
||||||
@ -157,24 +170,42 @@ class MeshConverter:
|
|||||||
# NOTE: Blender has no third (W) coordinate
|
# NOTE: Blender has no third (W) coordinate
|
||||||
tessface_uvws = [uvtex.data[i].uv for uvtex in mesh.tessface_uv_textures]
|
tessface_uvws = [uvtex.data[i].uv for uvtex in mesh.tessface_uv_textures]
|
||||||
|
|
||||||
|
# Unpack colors
|
||||||
|
if color is None:
|
||||||
|
tessface_colors = ((1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0))
|
||||||
|
else:
|
||||||
|
src = color[i]
|
||||||
|
tessface_colors = (src.color1, src.color2, src.color3, src.color4)
|
||||||
|
|
||||||
|
# Unpack alpha values
|
||||||
|
if alpha is None:
|
||||||
|
tessface_alphas = (1.0, 1.0, 1.0, 1.0)
|
||||||
|
else:
|
||||||
|
src = alpha[i]
|
||||||
|
# average color becomes the alpha value
|
||||||
|
tessface_alphas = (((src.color1[0] + src.color1[1] + src.color1[2]) / 3),
|
||||||
|
((src.color2[0] + src.color2[1] + src.color2[2]) / 3),
|
||||||
|
((src.color3[0] + src.color3[1] + src.color3[2]) / 3),
|
||||||
|
((src.color4[0] + src.color4[1] + src.color4[2]) / 3))
|
||||||
|
|
||||||
# Convert to per-material indices
|
# Convert to per-material indices
|
||||||
for j, vertex in enumerate(tessface.vertices):
|
for j, vertex in enumerate(tessface.vertices):
|
||||||
uvws = tuple([uvw[j] for uvw in tessface_uvws])
|
uvws = tuple([uvw[j] for uvw in tessface_uvws])
|
||||||
|
|
||||||
# Grab VCols (TODO--defaulting to white for now)
|
# Grab VCols
|
||||||
# This will be finalized once the vertex color light code baking is in
|
vertex_color = (int(tessface_colors[j][0] * 255), int(tessface_colors[j][1] * 255),
|
||||||
color = (255, 255, 255, 255)
|
int(tessface_colors[j][2] * 255), int(tessface_alphas[j] * 255))
|
||||||
|
|
||||||
# Now, we'll index into the vertex dict using the per-face elements :(
|
# Now, we'll index into the vertex dict using the per-face elements :(
|
||||||
# We're using tuples because lists are not hashable. The many mathutils and PyHSPlasma
|
# We're using tuples because lists are not hashable. The many mathutils and PyHSPlasma
|
||||||
# types are not either, and it's entirely too much work to fool with all that.
|
# types are not either, and it's entirely too much work to fool with all that.
|
||||||
coluv = (color, uvws)
|
coluv = (vertex_color, uvws)
|
||||||
if coluv not in data.blender2gs[vertex]:
|
if coluv not in data.blender2gs[vertex]:
|
||||||
source = mesh.vertices[vertex]
|
source = mesh.vertices[vertex]
|
||||||
geoVertex = plGeometrySpan.TempVertex()
|
geoVertex = plGeometrySpan.TempVertex()
|
||||||
geoVertex.position = utils.vector3(source.co)
|
geoVertex.position = utils.vector3(source.co)
|
||||||
geoVertex.normal = utils.vector3(source.normal)
|
geoVertex.normal = utils.vector3(source.normal)
|
||||||
geoVertex.color = hsColor32(*color)
|
geoVertex.color = hsColor32(*vertex_color)
|
||||||
geoVertex.uvs = [hsVector3(uv[0], uv[1], 0.0) for uv in uvws]
|
geoVertex.uvs = [hsVector3(uv[0], uv[1], 0.0) for uv in uvws]
|
||||||
data.blender2gs[vertex][coluv] = len(data.vertices)
|
data.blender2gs[vertex][coluv] = len(data.vertices)
|
||||||
data.vertices.append(geoVertex)
|
data.vertices.append(geoVertex)
|
||||||
@ -217,15 +248,10 @@ class MeshConverter:
|
|||||||
return diface.key
|
return diface.key
|
||||||
|
|
||||||
def _export_mesh(self, bo):
|
def _export_mesh(self, bo):
|
||||||
# Step 0.8: If this mesh wants to be light mapped, we need to go ahead and generate it.
|
# Step 0.8: If this mesh wants to be lit, we need to go ahead and generate it.
|
||||||
if bo.plasma_modifiers.lightmap.enabled:
|
self._export_static_lighting(bo)
|
||||||
print(" Baking lightmap...")
|
|
||||||
print("====")
|
|
||||||
bpy.context.scene.objects.active = bo
|
|
||||||
bpy.ops.object.plasma_lightmap_autobake()
|
|
||||||
print("====")
|
|
||||||
|
|
||||||
# Step 0.9: Update the mesh
|
# Step 0.9: Update the mesh such that we can do things and schtuff...
|
||||||
mesh = bo.data
|
mesh = bo.data
|
||||||
mesh.update(calc_tessface=True)
|
mesh.update(calc_tessface=True)
|
||||||
|
|
||||||
@ -263,6 +289,23 @@ class MeshConverter:
|
|||||||
geospans[i] = (self._create_geospan(bo, mesh, blmat, hsgmat), blmat.pass_index)
|
geospans[i] = (self._create_geospan(bo, mesh, blmat, hsgmat), blmat.pass_index)
|
||||||
return geospans
|
return geospans
|
||||||
|
|
||||||
|
def _export_static_lighting(self, bo):
|
||||||
|
if bo.plasma_modifiers.lightmap.enabled:
|
||||||
|
print(" Baking lightmap...")
|
||||||
|
print("====")
|
||||||
|
bpy.context.scene.objects.active = bo
|
||||||
|
bpy.ops.object.plasma_lightmap_autobake()
|
||||||
|
print("====")
|
||||||
|
else:
|
||||||
|
for vcol_layer in bo.data.vertex_colors:
|
||||||
|
name = vcol_layer.name.lower()
|
||||||
|
if name in _VERTEX_COLOR_LAYERS:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(" Baking crappy vertex color lighting...")
|
||||||
|
bpy.ops.object.plasma_vertexlight_autobake()
|
||||||
|
|
||||||
|
|
||||||
def _find_create_dspan(self, bo, hsgmat, pass_index):
|
def _find_create_dspan(self, bo, hsgmat, pass_index):
|
||||||
location = self._mgr.get_location(bo)
|
location = self._mgr.get_location(bo)
|
||||||
if location not in self._dspans:
|
if location not in self._dspans:
|
||||||
|
@ -16,14 +16,20 @@
|
|||||||
import bpy
|
import bpy
|
||||||
from ..helpers import GoodNeighbor
|
from ..helpers import GoodNeighbor
|
||||||
|
|
||||||
class _LightmapOperator:
|
class _LightingOperator:
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
if context.object is not None:
|
if context.object is not None:
|
||||||
return context.scene.render.engine == "PLASMA_GAME"
|
return context.scene.render.engine == "PLASMA_GAME"
|
||||||
|
|
||||||
|
def _hide_textures(self, mesh, toggle):
|
||||||
|
for mat in mesh.materials:
|
||||||
|
for tex in mat.texture_slots:
|
||||||
|
if tex is not None and tex.use:
|
||||||
|
toggle.track(tex, "use", False)
|
||||||
|
|
||||||
class LightmapAutobakeOperator(_LightmapOperator, bpy.types.Operator):
|
|
||||||
|
class LightmapAutobakeOperator(_LightingOperator, bpy.types.Operator):
|
||||||
bl_idname = "object.plasma_lightmap_autobake"
|
bl_idname = "object.plasma_lightmap_autobake"
|
||||||
bl_label = "Bake Lightmap"
|
bl_label = "Bake Lightmap"
|
||||||
bl_options = {"INTERNAL"}
|
bl_options = {"INTERNAL"}
|
||||||
@ -76,10 +82,9 @@ class LightmapAutobakeOperator(_LightmapOperator, bpy.types.Operator):
|
|||||||
toggle.track(render, "bake_type", "FULL")
|
toggle.track(render, "bake_type", "FULL")
|
||||||
toggle.track(render, "use_bake_to_vertex_color", False)
|
toggle.track(render, "use_bake_to_vertex_color", False)
|
||||||
|
|
||||||
for mat in obj.data.materials:
|
# If we run a full render with our textures enabled, guess what we will get in our LM?
|
||||||
for tex in mat.texture_slots:
|
# Yeah, textures. Mutter mutter mutter.
|
||||||
if tex is not None and tex.use:
|
self._hide_textures(obj.data, toggle)
|
||||||
toggle.track(tex, "use", False)
|
|
||||||
|
|
||||||
# Now, we *finally* bake the lightmap...
|
# Now, we *finally* bake the lightmap...
|
||||||
# FIXME: Don't bake Plasma RT lights
|
# FIXME: Don't bake Plasma RT lights
|
||||||
@ -89,7 +94,7 @@ class LightmapAutobakeOperator(_LightmapOperator, bpy.types.Operator):
|
|||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class LightmapAutobakePreviewOperator(_LightmapOperator, bpy.types.Operator):
|
class LightmapAutobakePreviewOperator(_LightingOperator, bpy.types.Operator):
|
||||||
bl_idname = "object.plasma_lightmap_preview"
|
bl_idname = "object.plasma_lightmap_preview"
|
||||||
bl_label = "Preview Lightmap"
|
bl_label = "Preview Lightmap"
|
||||||
bl_options = {"INTERNAL"}
|
bl_options = {"INTERNAL"}
|
||||||
@ -104,3 +109,35 @@ class LightmapAutobakePreviewOperator(_LightmapOperator, bpy.types.Operator):
|
|||||||
tex.image = bpy.data.images["{}_LIGHTMAPGEN".format(context.active_object.name)]
|
tex.image = bpy.data.images["{}_LIGHTMAPGEN".format(context.active_object.name)]
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class VertexColorLightingOperator(_LightingOperator, bpy.types.Operator):
|
||||||
|
bl_idname = "object.plasma_vertexlight_autobake"
|
||||||
|
bl_label = "Bake Vertex Color Lighting"
|
||||||
|
bl_options = {"INTERNAL"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
with GoodNeighbor() as toggle:
|
||||||
|
mesh = context.active_object.data
|
||||||
|
mesh.update()
|
||||||
|
|
||||||
|
# Find the "autocolor" vertex color layer
|
||||||
|
autocolor = mesh.vertex_colors.get("autocolor")
|
||||||
|
if autocolor is None:
|
||||||
|
mesh.vertex_colors.new("autocolor")
|
||||||
|
toggle.track(mesh.vertex_colors, "active", autocolor)
|
||||||
|
|
||||||
|
# Prepare to bake...
|
||||||
|
self._hide_textures(mesh, toggle)
|
||||||
|
# TODO: don't bake runtime lights
|
||||||
|
|
||||||
|
# Bake settings
|
||||||
|
render = context.scene.render
|
||||||
|
toggle.track(render, "bake_type", "FULL")
|
||||||
|
toggle.track(render, "use_bake_to_vertex_color", True)
|
||||||
|
|
||||||
|
# Bake
|
||||||
|
bpy.ops.object.bake_image()
|
||||||
|
|
||||||
|
# And done!
|
||||||
|
return {"FINISHED"}
|
||||||
|
Reference in New Issue
Block a user