mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 13:10:34 +00:00
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:
parent
c14e5623ad
commit
9d09d65d9a
3 changed files with 30 additions and 75 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue