Browse Source

Fix #63

pull/75/head
Adam Johnson 7 years ago
parent
commit
b98aec8840
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 63
      korman/exporter/convert.py
  2. 95
      korman/exporter/mesh.py

63
korman/exporter/convert.py

@ -53,7 +53,8 @@ class Exporter:
self.animation = animation.AnimationConverter(self) self.animation = animation.AnimationConverter(self)
self.sumfile = sumfile.SumFile() self.sumfile = sumfile.SumFile()
# Step 0.9: Init the progress mgr # Step 0.8: Init the progress mgr
self.report.progress_add_step("Applying Blender Mods")
self.report.progress_add_step("Collecting Objects") self.report.progress_add_step("Collecting Objects")
self.report.progress_add_step("Harvesting Actors") self.report.progress_add_step("Harvesting Actors")
if self._op.bake_lighting: if self._op.bake_lighting:
@ -65,44 +66,46 @@ class Exporter:
self.report.progress_add_step("Composing Geometry") self.report.progress_add_step("Composing Geometry")
self.report.progress_start("EXPORTING AGE") self.report.progress_start("EXPORTING AGE")
# Step 1: Create the age info and the pages # Step 0.9: Apply modifiers to all meshes temporarily.
self._export_age_info() with self.mesh:
# Step 1: Create the age info and the pages
self._export_age_info()
# Step 2: Gather a list of objects that we need to export, given what the user has told # Step 2: Gather a list of objects that we need to export, given what the user has told
# us to export (both in the Age and Object Properties)... fun # us to export (both in the Age and Object Properties)... fun
self._collect_objects() self._collect_objects()
# Step 2.5: Run through all the objects we collected in Step 2 and see if any relationships # Step 2.5: Run through all the objects we collected in Step 2 and see if any relationships
# that the artist made requires something to have a CoordinateInterface # that the artist made requires something to have a CoordinateInterface
self._harvest_actors() self._harvest_actors()
# Step 2.9: It is assumed that static lighting is available for the mesh exporter. # Step 2.9: It is assumed that static lighting is available for the mesh exporter.
# Indeed, in PyPRP it was a manual step. So... BAKE NAO! # Indeed, in PyPRP it was a manual step. So... BAKE NAO!
if self._op.bake_lighting: if self._op.bake_lighting:
self._bake_static_lighting() self._bake_static_lighting()
# Step 3: Export all the things! # Step 3: Export all the things!
self._export_scene_objects() self._export_scene_objects()
# Step 3.1: Ensure referenced logic node trees are exported # Step 3.1: Ensure referenced logic node trees are exported
self._export_referenced_node_trees() self._export_referenced_node_trees()
# Step 3.2: Now that all Plasma Objects (save Mipmaps) are exported, we do any post # Step 3.2: Now that all Plasma Objects (save Mipmaps) are exported, we do any post
# processing that needs to inspect those objects # processing that needs to inspect those objects
self._post_process_scene_objects() self._post_process_scene_objects()
# Step 4: Finalize... # Step 4: Finalize...
self.mesh.material.finalize() self.mesh.material.finalize()
self.mesh.finalize() self.mesh.finalize()
# Step 5: FINALLY. Let's write the PRPs and crap. # Step 5: FINALLY. Let's write the PRPs and crap.
self.mgr.save_age(Path(self._op.filepath)) self.mgr.save_age(Path(self._op.filepath))
# Step 5.1: Save out the export report. # Step 5.1: Save out the export report.
# If the export fails and this doesn't save, we have bigger problems than # If the export fails and this doesn't save, we have bigger problems than
# these little warnings and notices. # these little warnings and notices.
self.report.progress_end() self.report.progress_end()
self.report.save() self.report.save()
def _bake_static_lighting(self): def _bake_static_lighting(self):
oven = etlight.LightBaker(self.report) oven = etlight.LightBaker(self.report)

95
korman/exporter/mesh.py

@ -111,9 +111,42 @@ class _GeoData:
self.vertices = [] self.vertices = []
class MeshConverter:
class _MeshManager:
def __init__(self, exporter): def __init__(self, exporter):
self._exporter = weakref.ref(exporter) self._exporter = weakref.ref(exporter)
self._mesh_overrides = {}
def __enter__(self):
report = self._exporter().report
report.progress_advance()
report.progress_range = len(bpy.data.objects)
# Some modifiers like "Array" will procedurally generate new geometry that will impact
# lightmap generation. The Blender Internal renderer does not seem to be smart enough to
# take this into account. Thus, we temporarily apply modifiers to ALL meshes (even ones that
# are not exported) such that we can generate proper lighting.
scene = bpy.context.scene
for i in bpy.data.objects:
if i.type == "MESH" and i.is_modified(scene, "RENDER"):
# Remember, storing actual pointers to the Blender objects can cause bad things to
# happen because Blender's memory management SUCKS!
self._mesh_overrides[i.name] = i.data.name
i.data = i.to_mesh(scene, True, "RENDER", calc_tessface=False)
report.progress_increment()
return self
def __exit__(self, type, value, traceback):
data_bos, data_meshes = bpy.data.objects, bpy.data.meshes
for obj_name, mesh_name in self._mesh_overrides.items():
bo = data_bos.get(obj_name)
trash_mesh, bo.data = bo.data, data_meshes.get(mesh_name)
data_meshes.remove(trash_mesh)
class MeshConverter(_MeshManager):
def __init__(self, exporter):
super().__init__(exporter)
self.material = material.MaterialConverter(exporter) self.material = material.MaterialConverter(exporter)
self._dspans = {} self._dspans = {}
@ -403,8 +436,11 @@ class MeshConverter:
diface.addDrawable(dspan_key, idx) diface.addDrawable(dspan_key, idx)
def _export_mesh(self, bo): def _export_mesh(self, bo):
# Step 0.7: Update the mesh such that we can do things and schtuff... # Previously, this called bo.to_mesh to apply modifiers. However, due to limitations in the
mesh = bo.to_mesh(bpy.context.scene, True, "RENDER", calc_tessface=True) # lightmap generation, this is now done for all modified mesh objects before any Plasma data
# is exported.
mesh = bo.data
mesh.calc_tessface()
# Step 0.8: Figure out which materials are attached to this object. Because Blender is backwards, # Step 0.8: Figure out which materials are attached to this object. Because Blender is backwards,
# we can actually have materials that are None. gotdawgit!!! # we can actually have materials that are None. gotdawgit!!!
@ -412,33 +448,32 @@ class MeshConverter:
if not materials: if not materials:
return None return None
with helpers.TemporaryObject(mesh, bpy.data.meshes.remove): # Step 1: Export all of the doggone materials.
# Step 1: Export all of the doggone materials. geospans = self._export_material_spans(bo, mesh, materials)
geospans = self._export_material_spans(bo, mesh, materials)
# Step 2: Export Blender mesh data to Plasma GeometrySpans
# Step 2: Export Blender mesh data to Plasma GeometrySpans self._export_geometry(bo, mesh, materials, geospans)
self._export_geometry(bo, mesh, materials, geospans)
# Step 3: Add plGeometrySpans to the appropriate DSpan and create indices
# Step 3: Add plGeometrySpans to the appropriate DSpan and create indices _diindices = {}
_diindices = {} for geospan, pass_index in geospans:
for geospan, pass_index in geospans: dspan = self._find_create_dspan(bo, geospan.material.object, pass_index)
dspan = self._find_create_dspan(bo, geospan.material.object, pass_index) self._report.msg("Exported hsGMaterial '{}' geometry into '{}'",
self._report.msg("Exported hsGMaterial '{}' geometry into '{}'", geospan.material.name, dspan.key.name, indent=1)
geospan.material.name, dspan.key.name, indent=1) idx = dspan.addSourceSpan(geospan)
idx = dspan.addSourceSpan(geospan) if dspan not in _diindices:
if dspan not in _diindices: _diindices[dspan] = [idx,]
_diindices[dspan] = [idx,] else:
else: _diindices[dspan].append(idx)
_diindices[dspan].append(idx)
# Step 3.1: Harvest Span indices and create the DIIndices
# Step 3.1: Harvest Span indices and create the DIIndices drawables = []
drawables = [] for dspan, indices in _diindices.items():
for dspan, indices in _diindices.items(): dii = plDISpanIndex()
dii = plDISpanIndex() dii.indices = indices
dii.indices = indices idx = dspan.addDIIndex(dii)
idx = dspan.addDIIndex(dii) drawables.append((dspan.key, idx))
drawables.append((dspan.key, idx)) return drawables
return drawables
def _export_material_spans(self, bo, mesh, materials): def _export_material_spans(self, bo, mesh, materials):
"""Exports all Materials and creates plGeometrySpans""" """Exports all Materials and creates plGeometrySpans"""

Loading…
Cancel
Save