Script Exportacion Project Zomboid Modelos Blender
Script Exportacion Project Zomboid Modelos Blender
php/topic/12864-blen
der
# Exports models to Zomboid format.
import io, math, bmesh, bpy
from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator
from mathutils import Vector, Euler, Quaternion, Matrix
class ZomboidExport(Operator, ExportHelper):
bl_idname
= "zomboid.export_model"
bl_label
= "Export a Zomboid Model"
filename_ext = ".txt"
filter_glob = StringProperty(
default="*.txt",
options={'HIDDEN'},
)
#use_setting = BoolProperty(
#
name="Example Boolean",
#
description="Example Tooltip",
#
default=True,
#
)
#type = EnumProperty(
#
name="Example Enum",
#
description="Choose between two items",
#
items=(('OPT_A', "First Option", "Description one"),
#
('OPT_B', "Second Option", "Description two")),
#
default='OPT_A',
#
)
def prepare_mesh(self):
self.object_original = bpy.context.active_object
# Grab the name of the selected object
self.mesh_name = self.object_original.name
# Duplicate the object to modify without affecting the actual model
bpy.ops.object.duplicate()
object = self.object = bpy.context.active_object
mesh = self.mesh = object.data
# We need to be in edit-mode to fix up the duplicate
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.mesh.select_all(action='SELECT')
# In order to be a valid format, the mesh needs to be
#
in triangulated.
bpy.ops.mesh.quads_convert_to_tris()
# Go back to Object mode to apply polygon modifications.
bpy.ops.object.mode_set(mode = 'OBJECT')
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.object.mode_set(mode = 'OBJECT')
# Grab the count of vertices.
self.mesh_vertex_count = len(object.data.vertices)
# Create a boolean for asking if the mesh has uv map data
has_uv_mapping = self.mesh_has_uv_mapping = len(mesh.uv_textures) > 0
# Assign UV Map data if it exists.
if has_uv_mapping:
self.vertex_stride_element_count += 1
self.uv_texture = mesh.uv_textures.active.data[:]
self.uv_layer = mesh.uv_layers.active.data[:]
# Calculate face normals
mesh.calc_normals_split()
self.mesh_loops = mesh.loops
for modifier in object.modifiers:
if modifier.type == 'ARMATURE':
if object.parent.type == 'ARMATURE':
if object.parent['ZOMBOID_ARMATURE'] == 1:
self.vertex_stride_element_count += 3
self.armature = object.parent.data
self.mesh_has_bone_weights = True
self.mesh_has_tangent_array = True
print("Armature modifier detected. Exporting with bone w
eights.")
def process_mesh(self):
self.global_matrix = Matrix()
self.mesh_matrix = self.object.matrix_world
object
= self.object
mesh
= self.mesh
mesh_matrix = self.mesh_matrix
if self.mesh_has_bone_weights:
vert_weight_id
= []
vert_weight_value = []
bone_id_table
weight_data
weight_bone_names
weight_vert_data
=
=
=
=
get_bone_id_table(object.parent)
mesh_to_weight_list(object, mesh)
weight_data[0]
weight_data[1]
if offset < 4:
while offset <
weights +=
indexes +=
offset +=
4:
"-1.0, "
"0, "
1
vert_weight_id.append(indexes[:-2])
vert_weight_value.append(weights[:-2])
mesh.update(calc_tessface=True)
for f in mesh.polygons:
face = Face()
face.id = f.index
for i in f.loop_indices:
l = mesh.loops[i]
v = mesh.vertices[l.vertex_index]
vert = Vertex()
vid = vert.id = l.vertex_index
vert.co = v.co
vert.normal = v.normal
# If UV mapping, then add this data.
if self.mesh_has_uv_mapping:
uvl = 0
for j,ul in enumerate(mesh.uv_layers):
vert.texture_coord = ul.data[l.index].uv
uvl += 1
# If Bone Weights, add this data.
if self.mesh_has_bone_weights:
vert.blend_weight = vert_weight_value[vid]
vert.blend_index = vert_weight_id[vid]
face.verts.append(vert)
self.faces.append(face)
# Optimize the face vert count
# Temporary containers & flags
verts
= []
has_vert = dict()
vert_index = dict()
# Offset for the new index
vert_offset = 0
# Go through each face
for f in self.faces:
# Go through each vertex
for index in range(0,len(face.verts)):
# Grab the vertex
f_v = f.verts[index]
# Create the Unique key for compared data.
key = str(f_v.co) + " " + str(f_v.texture_coord)
try:
)
)
)
)
)
)
)
)
)
)
= []
= []
self.global_matrix
= None
self.object_original
self.object
self.armature
self.mesh
self.mesh_name
self.mesh_matrix
self.mesh_loops
=
=
=
=
=
=
=
None
None
None
None
"Untitled_Mesh"
None
None
self.vertex_array_name
self.normal_array_name
self.tangent_array_name
self.texture_coord_array_name
self.blend_weight_array_name
=
=
=
=
=
'VertexArray'
'NormalArray'
'TangentArray'
'TextureCoordArray'
'BlendWeightArray'
self.blend_index_array_name
= 'BlendIndexArray'
self.mesh_vertex_count
= 0
self.offset_vertex_array
self.offset_normal_array
self.offset_tangent_array
self.offset_texture_coord_array
self.offset_blend_weight_array
self.offset_blend_index_array
=
=
=
=
=
=
12
12
12
8
16
0
self.vertex_stride_element_count
self.mesh_has_vertex_array
self.mesh_has_normal_array
self.mesh_has_tangent_array
self.mesh_has_uv_mapping
self.mesh_has_bone_weights
=
=
=
=
=
=
2
True
True
False
False
False
class Vertex:
def __init__(self):
self.mesh_vertex
self.polygon
= None
= None
self.co
self.normal
self.tangent
self.texture_coord
=
=
=
=
Vector((0.0,0.0,0.0))
Vector((0.0,0.0,0.0))
Vector((0.0,0.0,0.0))
Vector((0.0,0.0))
self.blend_weight
self.blend_index
= []
= []
self.id
self.original_vert_id
= -1
= -1
class Face:
def __init__(self):
self.vert_ids
self.verts
self.id
= []
= []
= -1
register()
bpy.ops.zomboid.export_model('INVOKE_DEFAULT')
################################################################################
#####
###
###
### File I/O methods
###
###
###
################################################################################
#####
# Writes a line to the file.
def write_line(file, line, new_line=True):
# Converts any arbitrary primitives into a String just in-case.
finished_line = str(line)
# If new_line is true, add a newline marker at the end.
if new_line:
finished_line = finished_line + "\n"
# Write the line to a file.
file.write(finished_line)
def write(file, line):
write_line(file, line, new_line=False)
# Writes a comment to the file.
def write_comment(file, comment):
final_comment = "# " + str(comment)
write_line(file, final_comment)
def write_vector_3(file, vector):
string = str(round(vector[0], 8)) + ", " + str(round(vector[1], 8)) + ", " +
str(round(vector[2], 8))
write_line(file, string)
def write_uv(file, vector):
#print("Vec2: " + str(vector))
string = str(round(vector[0], 8)) + ", " + str(round(1.0 - vector[1], 8))
write_line(file, string)
def write_weights(file, vector):
write_line(file, vector.blend_weight)
write_line(file, vector.blend_index)
def write_array(file, array):
string = ""
bone_ids
= dict()