diff --git a/korman/exporter/physics.py b/korman/exporter/physics.py
index b02a249..d13f221 100644
--- a/korman/exporter/physics.py
+++ b/korman/exporter/physics.py
@@ -13,13 +13,15 @@
# You should have received a copy of the GNU General Public License
# along with Korman. If not, see .
+import bmesh
import bpy
+import itertools
import mathutils
from PyHSPlasma import *
import weakref
from .explosions import ExportError, ExportAssertionError
-from ..helpers import TemporaryObject
+from ..helpers import bmesh_from_object, TemporaryObject
from . import utils
def _set_phys_prop(prop, sim, phys, value=True):
@@ -58,18 +60,11 @@ class PhysicsConverter:
indices += (v[0], v[2], v[3],)
return indices
- def _convert_mesh_data(self, bo, physical, local_space, indices=True, mesh_func=None):
- try:
- mesh = bo.to_mesh(bpy.context.scene, True, "RENDER", calc_tessface=False)
- except:
- raise ExportError("Unable to convert object [{}] '{}' to a mesh. Make sure you didn't try to use this object as a region!",
- bo.type, bo.name)
+ def _convert_mesh_data(self, bo, physical, local_space, indices=True):
mat = bo.matrix_world
+ mesh = bo.to_mesh(bpy.context.scene, True, "RENDER", calc_tessface=False)
with TemporaryObject(mesh, bpy.data.meshes.remove):
- if mesh_func is not None:
- mesh_func(mesh)
-
if local_space:
mesh.update(calc_tessface=indices)
physical.pos = hsVector3(*mat.to_translation())
@@ -264,21 +259,19 @@ class PhysicsConverter:
# Only certain builds of libHSPlasma are able to take artist generated triangle soups and
# bake them to convex hulls. Specifically, Windows 32-bit w/PhysX 2.6. Everything else just
# needs to have us provide some friendlier data...
- def _bake_hull(mesh):
- # The bmesh API for doing this is trash, so we will link this temporary mesh to an
- # even more temporary object so we can use the traditional operator.
- # Unless you want to write some code to do this by hand...??? (not me)
- bo = bpy.data.objects.new("BMeshSucks", mesh)
- bpy.context.scene.objects.link(bo)
- with TemporaryObject(bo, bpy.data.objects.remove):
- bpy.context.scene.objects.active = bo
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_all(action="SELECT")
- bpy.ops.mesh.convex_hull(use_existing_faces=False)
- bpy.ops.object.mode_set(mode="OBJECT")
-
- physical.verts = self._convert_mesh_data(bo, physical, local_space, indices=False,
- mesh_func=_bake_hull)
+ with bmesh_from_object(bo) as mesh:
+ mat = bo.matrix_world
+ if local_space:
+ physical.pos = hsVector3(*mat.to_translation())
+ physical.rot = utils.quaternion(mat.to_quaternion())
+ bmesh.ops.scale(mesh, vec=mat.to_scale(), verts=mesh.verts)
+ else:
+ mesh.transform(mat)
+
+ result = bmesh.ops.convex_hull(mesh, input=mesh.verts, use_existing_faces=False)
+ BMVert = bmesh.types.BMVert
+ verts = itertools.takewhile(lambda x: isinstance(x, BMVert), result["geom"])
+ physical.verts = [hsVector3(*i.co) for i in verts]
def _export_sphere(self, bo, physical, local_space):
"""Exports sphere bounds based on the object"""
diff --git a/korman/helpers.py b/korman/helpers.py
index 9e16819..31c1d20 100644
--- a/korman/helpers.py
+++ b/korman/helpers.py
@@ -13,9 +13,22 @@
# You should have received a copy of the GNU General Public License
# along with Korman. If not, see .
+import bmesh
import bpy
+from contextlib import contextmanager
import math
+@contextmanager
+def bmesh_from_object(bl):
+ """Converts a Blender Object to a BMesh with modifiers applied."""
+ mesh = bmesh.new()
+ try:
+ # Empirical evidence indicates that this applies Blender Modifiers
+ mesh.from_object(bl, bpy.context.scene)
+ yield mesh
+ finally:
+ mesh.free()
+
class GoodNeighbor:
"""Leave Things the Way You Found Them! (TM)"""