]> git.tdb.fi Git - libs/gl.git/commitdiff
Support defining and exporting object LoDs in Blender
authorMikko Rasa <tdb@tdb.fi>
Sun, 7 Dec 2014 23:17:15 +0000 (01:17 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 7 Dec 2014 23:17:15 +0000 (01:17 +0200)
blender/io_mspgl/__init__.py
blender/io_mspgl/export_object.py
blender/io_mspgl/properties.py

index b1bb2f0de8c83c9af12ebace525624c66582194c..2c9d8f721a6bb7cec65d04a9159933ffadc5ff64 100644 (file)
@@ -111,6 +111,8 @@ class ExportMspGLObject(bpy.types.Operator, ExportMspGLMeshBase):
        separate_tech = bpy.props.BoolProperty(name="Separate technique", description="Write technique data into a separate file", default=False)
        shared_tech = bpy.props.BoolProperty(name="Shared technique", description="Use material name for technique file to enable sharing", default=True)
 
+       export_lods = bpy.props.BoolProperty(name="Export LoDs", description="Export all levels of detail", default=True)
+
        def create_exporter(self):
                from .export_object import ObjectExporter
                return ObjectExporter()
@@ -120,6 +122,7 @@ class ExportMspGLObject(bpy.types.Operator, ExportMspGLMeshBase):
 
                col = self.general_col
                col.prop(self, "external_tech")
+               col.prop(self, "export_lods")
 
                col = self.texturing_col
                col.prop(self, "textures")
index 09703e58e902a1847e2b70d3e145117094296122..b910add12fad3ed86ef397861de92fc8bb6a50b9 100644 (file)
@@ -13,6 +13,13 @@ def image_name(i):
        else:
                return i.name
 
+def external_name(out_file, ext, index):
+       path, base = os.path.split(out_file.filename)
+       base = os.path.splitext(base)[0]
+       if index>0:
+               base += "_lod{}".format(index)
+       return path, base+ext
+
 
 class ObjectExporter:
        def __init__(self):
@@ -23,6 +30,7 @@ class ObjectExporter:
                self.separate_tech = False
                self.external_tech = True
                self.shared_tech = True
+               self.export_lods = True
 
        def export(self, context, out_file, objs=None, progress=None):
                if objs is None:
@@ -30,35 +38,80 @@ class ObjectExporter:
                else:
                        obj = objs[0]
 
+               lods = [obj]
+               for c in obj.children:
+                       if c.lod_for_parent:
+                               if c.lod_index>=len(lods):
+                                       lods += [None]*(c.lod_index+1-len(lods))
+                               lods[c.lod_index] = c
+
                from .outfile import open_output
                out_file = open_output(out_file)
-               path, base = os.path.split(out_file.filename)
 
+               prev_mesh = None
+               prev_tech = (None, None)
+               for i, l in enumerate(lods):
+                       if i>0:
+                               out_file.begin("level_of_detail", i)
+                               objs = [l]
+
+                       same_mesh = (l.data.name==prev_mesh)
+                       if i==0 or not same_mesh:
+                               mesh = self.export_object_mesh(context, out_file, i, objs, progress)
+                               prev_mesh = l.data.name
+
+                       same_tech = True
+                       mat = None
+                       if l.material_slots and l.material_slots[0].material:
+                               mat = l.material_slots[0].material.name
+                               if mat!=prev_tech[1]:
+                                       same_tech = False
+                       if self.external_tech and l.technique!=prev_tech[0]:
+                               same_tech = False
+                       if i==0 or not same_tech:
+                               self.export_object_technique(l, mesh, out_file, i)
+                               prev_tech = (l.technique, mat)
+
+                       if i>0:
+                               out_file.end()
+
+       def export_object_mesh(self, context, out_file, lod_index, objs, progress):
                from .export_mesh import MeshExporter
                mesh_export = MeshExporter()
                for k, v in self.__dict__.items():
                        setattr(mesh_export, k, v)
 
                if self.separate_mesh:
-                       base, ext = os.path.splitext(base)
-                       mesh_out = open_output(os.path.join(path, base+".mesh"))
+                       from .outfile import open_output
+                       path, name = external_name(out_file, ".mesh", lod_index)
+                       mesh_out = open_output(os.path.join(path, name))
                        mesh = mesh_export.export(context, mesh_out, objs, progress)
-                       out_file.write("mesh", '"{}.mesh"'.format(base))
+                       out_file.write("mesh", '"{}"'.format(name))
                else:
                        out_file.begin("mesh")
                        mesh = mesh_export.export(context, out_file, objs, progress)
                        out_file.end()
 
+               return mesh
+
+       def export_object_technique(self, obj, mesh, out_file, lod_index):
                if self.srgb_colors:
                        self.colormap = linear_to_srgb
                else:
                        self.colormap = lambda x: x
 
+               material = None
+               if obj.material_slots:
+                       material = obj.material_slots[0].material
+
+               from .outfile import open_output
+               path, name = external_name(out_file, ".tech", lod_index)
+
                if self.external_tech and obj.technique:
-                       if obj.inherit_tech and (obj.override_material or mesh.materials[0].texture_slots):
+                       if obj.inherit_tech and material and (obj.override_material or material.texture_slots):
                                out_file.begin("technique")
                                out_file.begin("inherit", '"{}"'.format(obj.technique))
-                               for slot in mesh.materials[0].texture_slots:
+                               for slot in material.texture_slots:
                                        if slot and slot.texture.type=="IMAGE":
                                                name = image_name(slot.texture.image)
                                                if slot.use_map_color_diffuse:
@@ -66,31 +119,28 @@ class ObjectExporter:
                                                elif slot.use_map_normal:
                                                        out_file.write("texture", '"normal_map"', '"{}"'.format(name))
                                if obj.override_material:
-                                       mat_name = mesh.materials[0].name+".mat"
+                                       mat_name = material.name+".mat"
                                        mat_out = open_output(os.path.join(path, mat_name))
-                                       self.export_material(mesh.materials[0], mat_out)
+                                       self.export_material(material, mat_out)
                                        out_file.write("material", '""', '"{}"'.format(mat_name))
                                out_file.end()
                                out_file.end()
                        else:
                                out_file.write("technique", '"{}"'.format(obj.technique))
                elif self.separate_tech:
-                       if self.shared_tech and mesh.materials:
-                               tech_name = mesh.materials[0].name+".tech"
-                       else:
-                               base, ext = os.path.splitext(base)
-                               tech_name = base+".tech"
-                       tech_out = open_output(os.path.join(path, tech_name))
-                       self.export_technique(mesh, tech_out)
-                       out_file.write("technique", '"{}"'.format(tech_name))
+                       if self.shared_tech and material:
+                               name = material.name+".tech"
+                       tech_out = open_output(os.path.join(path, name))
+                       self.export_technique_definition(material, mesh, tech_out)
+                       out_file.write("technique", '"{}"'.format(name))
                else:
                        out_file.begin("technique")
-                       self.export_technique(mesh, out_file)
+                       self.export_technique_definition(material, mesh, out_file)
                        out_file.end()
 
-       def export_technique(self, mesh, out_file):
+       def export_technique_definition(self, material, mesh, out_file):
                out_file.begin("pass", '""')
-               if mesh.materials:
+               if material:
                        cm = self.colormap
 
                        if self.material_tex:
@@ -116,11 +166,11 @@ class ObjectExporter:
                                out_file.end()
                        else:
                                out_file.begin("material")
-                               self.export_material(mesh.materials[0], out_file)
+                               self.export_material(material, out_file)
                                out_file.end()
 
                        if self.textures!="NONE":
-                               for slot in mesh.materials[0].texture_slots:
+                               for slot in material.texture_slots:
                                        if not slot:
                                                continue
 
index 9d0d666a4f35661b3ce279fdf77a468040745d66..30aed9a906187bf132c6319a590893e01fd07ecd 100644 (file)
@@ -15,9 +15,14 @@ class MspGLProperties(bpy.types.Panel):
                if obj.inherit_tech:
                        self.layout.prop(obj, "override_material");
                self.layout.prop(obj, "compound");
+               self.layout.prop(obj, "lod_for_parent")
+               if obj.lod_for_parent:
+                       self.layout.prop(obj, "lod_index")
 
 def register_properties():
        bpy.types.Object.technique = bpy.props.StringProperty(name="Technique", description="Name of the technique to use for rendering")
        bpy.types.Object.inherit_tech = bpy.props.BoolProperty(name="Inherit technique", description="Inherit from the technique to customize textures")
        bpy.types.Object.override_material = bpy.props.BoolProperty(name="Override material", description="Override material in the inherited texture as well", default=True)
        bpy.types.Object.compound = bpy.props.BoolProperty(name="Compound with parent", description="Join this object to its parent when exporting")
+       bpy.types.Object.lod_for_parent = bpy.props.BoolProperty(name="LoD for parent", description="This object is a level of detail for its parent")
+       bpy.types.Object.lod_index = bpy.props.IntProperty(name="LoD index", description="Index of the level of detail", min=1, default=1)