Clean up some export stuff

While it's not there yet, the eventual goal is to support multiple
models in the one blend file, so per-object settings is a requirement.
This commit is contained in:
Bill Currie 2019-08-20 16:52:43 +09:00
parent c14e5623ad
commit 9d09d65d9a
3 changed files with 30 additions and 75 deletions

View file

@ -119,34 +119,10 @@ class ExportMDL6(bpy.types.Operator, ExportHelper):
bl_idname = "export_mesh.quake_mdl_v6" bl_idname = "export_mesh.quake_mdl_v6"
bl_label = "Export MDL" bl_label = "Export MDL"
bl_options = {'PRESET'};
filename_ext = ".mdl" filename_ext = ".mdl"
filter_glob : StringProperty(default="*.mdl", options={'HIDDEN'}) filter_glob : StringProperty(default="*.mdl", options={'HIDDEN'})
eyeposition : FloatVectorProperty(
name="Eye Position",
description="View possion relative to object origin")
synctype : EnumProperty(
items=SYNCTYPE,
name="Sync Type",
description="Add random time offset for automatic animations")
rotate : BoolProperty(
name="Rotate",
description="Rotate automatically (for pickup items)",
default=False)
effects : EnumProperty(
items=EFFECTS,
name="Effects",
description="Particle trail effects")
xform : BoolProperty(
name="Auto transform",
description="Auto-apply location/rotation/scale when exporting",
default=True)
md16 : BoolProperty(
name="16-bit",
description="16 bit vertex coordinates: QuakeForge only")
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return (context.active_object != None return (context.active_object != None

View file

@ -96,7 +96,7 @@ def make_skin(operator, mdl, mesh):
mdl.skinwidth, mdl.skinheight = (4, 4) mdl.skinwidth, mdl.skinheight = (4, 4)
skin = null_skin((mdl.skinwidth, mdl.skinheight)) skin = null_skin((mdl.skinwidth, mdl.skinheight))
materials = bpy.context.object.data.materials materials = mesh.materials
if len(materials) > 0: if len(materials) > 0:
for mat in materials: for mat in materials:
@ -189,15 +189,8 @@ def convert_stverts(mdl, stverts):
t = ((t % mdl.skinheight) + mdl.skinheight) % mdl.skinheight t = ((t % mdl.skinheight) + mdl.skinheight) % mdl.skinheight
stverts[i] = MDL.STVert((s, t)) stverts[i] = MDL.STVert((s, t))
def make_frame(mesh, vertmap, idx): def make_frame(mesh, vertmap):
frame = MDL.Frame() frame = MDL.Frame()
frame.name = "frame" + str(idx)
if bpy.context.object.data.shape_keys:
shape_keys_amount = len(bpy.context.object.data.shape_keys.key_blocks)
if shape_keys_amount > idx:
frame.name = bpy.context.object.data.shape_keys.key_blocks[idx].name
for v in vertmap: for v in vertmap:
mv = mesh.vertices[v] mv = mesh.vertices[v]
vert = MDL.Vert(tuple(mv.co), map_normal(mv.normal)) vert = MDL.Vert(tuple(mv.co), map_normal(mv.normal))
@ -229,20 +222,12 @@ def calc_average_area(mdl):
totalarea += (c @ c) ** 0.5 / 2.0 totalarea += (c @ c) ** 0.5 / 2.0
return totalarea / len(mdl.tris) return totalarea / len(mdl.tris)
def get_properties( def get_properties(operator, mdl, obj):
operator, mdl.eyeposition = tuple(obj.qfmdl.eyeposition)
mdl, mdl.synctype = MDL.SYNCTYPE[obj.qfmdl.synctype]
eyeposition, mdl.flags = ((obj.qfmdl.rotate and MDL.EF_ROTATE or 0)
synctype, | MDL.EFFECTS[obj.qfmdl.effects])
rotate, if obj.qfmdl.md16:
effects,
xform,
md16):
mdl.eyeposition = eyeposition
mdl.synctype = MDL.SYNCTYPE[synctype]
mdl.flags = ((rotate and MDL.EF_ROTATE or 0)
| MDL.EFFECTS[effects])
if md16:
mdl.ident = "MD16" mdl.ident = "MD16"
script = obj.qfmdl.script script = obj.qfmdl.script
@ -315,26 +300,24 @@ def process_frame(mdl, scene, frame, vertmap, ingroup = False,
return fr return fr
mdl.frames += fr.frames[:-1] mdl.frames += fr.frames[:-1]
return fr.frames[-1] return fr.frames[-1]
scene.frame_set(int(frameno), frameno - int(frameno)) scene.frame_set(int(frameno), subframe = frameno - int(frameno))
mesh = mdl.obj.to_mesh(scene, True, 'PREVIEW') #wysiwyg? depsgraph = bpy.context.evaluated_depsgraph_get()
mesh = mdl.obj.evaluated_get(depsgraph).to_mesh() #wysiwyg?
if mdl.obj.qfmdl.xform: if mdl.obj.qfmdl.xform:
mesh.transform(mdl.obj.matrix_world) mesh.transform(mdl.obj.matrix_world)
fr = make_frame(mesh, vertmap) fr = make_frame(mesh, vertmap)
fr.name = name fr.name = name
return fr return fr
def export_mdl( def get_frame_name(mesh, idx):
operator, name = "frame" + str(idx)
context, if mesh.shape_keys:
filepath = "", shape_keys_amount = len(mesh.shape_keys.key_blocks)
eyeposition = (0.0, 0.0, 0.0), if shape_keys_amount > idx:
synctype = SYNCTYPE[1], name = mesh.shape_keys.key_blocks[idx].name
rotate = False, return name
effects = EFFECTS[1],
xform = True,
md16 = False
):
def export_mdl(operator, context, filepath):
obj = context.active_object obj = context.active_object
obj.update_from_editmode() obj.update_from_editmode()
depsgraph = context.evaluated_depsgraph_get() depsgraph = context.evaluated_depsgraph_get()
@ -346,16 +329,8 @@ def export_mdl(
# return {'CANCELLED'} # return {'CANCELLED'}
mdl = MDL(obj.name) mdl = MDL(obj.name)
mdl.obj = obj mdl.obj = obj
if not get_properties( if not get_properties(operator, mdl, obj):
operator, return {'CANCELLED'}
mdl,
eyeposition,
synctype,
rotate,
effects,
xform,
md16):
return {'CANCELLED'}
mdl.tris, mdl.stverts, vertmap = build_tris(mesh) mdl.tris, mdl.stverts, vertmap = build_tris(mesh)
if mdl.script: if mdl.script:
@ -369,15 +344,19 @@ def export_mdl(
if not mdl.skins: if not mdl.skins:
make_skin(operator, mdl, mesh) make_skin(operator, mdl, mesh)
if not mdl.frames: if not mdl.frames:
for fno in range(context.scene.frame_start, context.scene.frame_end + 1): scene = context.scene
for fno in range(scene.frame_start, scene.frame_end + 1):
context.scene.frame_set(fno) context.scene.frame_set(fno)
obj.update_from_editmode() obj.update_from_editmode()
depsgraph = context.evaluated_depsgraph_get() depsgraph = context.evaluated_depsgraph_get()
ob_eval = obj.evaluated_get(depsgraph) ob_eval = obj.evaluated_get(depsgraph)
mesh = ob_eval.to_mesh() mesh = ob_eval.to_mesh()
if xform: if obj.qfmdl.xform:
mesh.transform(mdl.obj.matrix_world) mesh.transform(mdl.obj.matrix_world)
mdl.frames.append(make_frame(mesh, vertmap, fno)) frame = make_frame(mesh, vertmap)
frame.name = get_frame_name(obj.data, fno)
mdl.frames.append(frame)
convert_stverts(mdl, mdl.stverts) convert_stverts(mdl, mdl.stverts)
mdl.size = calc_average_area(mdl) mdl.size = calc_average_area(mdl)
scale_verts(mdl) scale_verts(mdl)

View file

@ -296,8 +296,8 @@ def write_text(mdl):
/* This script represents the animation data within the model file. It /* This script represents the animation data within the model file. It
is generated automatically on import, and is optional when exporting. is generated automatically on import, and is optional when exporting.
If no script is used when exporting, frames will be exported one per If no script is used when exporting, frames will be exported one per
blender frame from frame 1 to the current frame (inclusive), and only blender frame from the scene start frame to the scene end frame
one skin will be exported. (inclusive), and one skin per teximage node will be exported.
The fundamental format of the script is documented at The fundamental format of the script is documented at
http://quakeforge.net/doxygen/property-list.html http://quakeforge.net/doxygen/property-list.html