|
@@ -28,6 +28,7 @@ class Vertex:
|
|
|
self.bones_count = 0
|
|
self.bones_count = 0
|
|
|
self.bone_ids = [-1, -1, -1, -1]
|
|
self.bone_ids = [-1, -1, -1, -1]
|
|
|
self.weights = [-1.0, -1.0, -1.0, -1.0]
|
|
self.weights = [-1.0, -1.0, -1.0, -1.0]
|
|
|
|
|
+ self.index = -1
|
|
|
|
|
|
|
|
def __eq__(self, b):
|
|
def __eq__(self, b):
|
|
|
return self.position == b.position and self.uv == b.uv \
|
|
return self.position == b.position and self.uv == b.uv \
|
|
@@ -46,7 +47,10 @@ class Mesh:
|
|
|
self.name = ""
|
|
self.name = ""
|
|
|
self.vertices = []
|
|
self.vertices = []
|
|
|
self.indices = []
|
|
self.indices = []
|
|
|
- self.id = "" # The mesh:id
|
|
|
|
|
|
|
+ self.id = "" # The mesh:id needed for skinning
|
|
|
|
|
+ # The mesh/source/float_array that includes the vertex positions.
|
|
|
|
|
+ # Needed for skinning
|
|
|
|
|
+ self.vert_positions = None
|
|
|
|
|
|
|
|
def compare_arr(a, b):
|
|
def compare_arr(a, b):
|
|
|
""" Compare 2 arrays """
|
|
""" Compare 2 arrays """
|
|
@@ -60,6 +64,13 @@ def compare_arr(a, b):
|
|
|
|
|
|
|
|
return True
|
|
return True
|
|
|
|
|
|
|
|
|
|
+def search_in_array(arr, el):
|
|
|
|
|
+ """ Self explanatory. Return index in array or -1 if not found """
|
|
|
|
|
+ for i in range(0, len(arr)):
|
|
|
|
|
+ if arr[i] == el:
|
|
|
|
|
+ return i
|
|
|
|
|
+ return -1
|
|
|
|
|
+
|
|
|
def parse_commandline():
|
|
def parse_commandline():
|
|
|
""" Parse the command line arguments """
|
|
""" Parse the command line arguments """
|
|
|
parser = optparse.OptionParser("usage: %prog [options]")
|
|
parser = optparse.OptionParser("usage: %prog [options]")
|
|
@@ -143,27 +154,29 @@ def get_positions_and_uvs(mesh_el):
|
|
|
if uvs_float_array == None:
|
|
if uvs_float_array == None:
|
|
|
raise Exception("UVs not found")
|
|
raise Exception("UVs not found")
|
|
|
|
|
|
|
|
- return (positions_float_array, int(positions_offset),
|
|
|
|
|
- uvs_float_array, int(uvs_offset))
|
|
|
|
|
|
|
+ # Convert the positions float array to a Vector array
|
|
|
|
|
+ positions_vec_array = []
|
|
|
|
|
+ for i in range(int(len(positions_float_array) / 3)):
|
|
|
|
|
+ x = positions_float_array[i * 3]
|
|
|
|
|
+ y = positions_float_array[i * 3 + 1]
|
|
|
|
|
+ z = positions_float_array[i * 3 + 2]
|
|
|
|
|
+ vec = Vector(x, y, z)
|
|
|
|
|
+ positions_vec_array.append(vec)
|
|
|
|
|
|
|
|
-def search_in_array(arr, el):
|
|
|
|
|
- """ XXX """
|
|
|
|
|
- for i in range(0, len(arr)):
|
|
|
|
|
- if arr[i] == el:
|
|
|
|
|
- return i
|
|
|
|
|
- return -1
|
|
|
|
|
|
|
+ return (positions_vec_array, int(positions_offset),
|
|
|
|
|
+ uvs_float_array, int(uvs_offset))
|
|
|
|
|
|
|
|
def parse_geometry(geometry_el):
|
|
def parse_geometry(geometry_el):
|
|
|
""" XXX """
|
|
""" XXX """
|
|
|
|
|
|
|
|
geom_name = geometry_el.get("name")
|
|
geom_name = geometry_el.get("name")
|
|
|
geom_id = geometry_el.get("id")
|
|
geom_id = geometry_el.get("id")
|
|
|
- print("---- Parshing geometry: %s" % geom_name)
|
|
|
|
|
|
|
+ print("---- Parsing geometry: %s" % geom_name)
|
|
|
|
|
|
|
|
mesh_el = geometry_el.find("mesh")
|
|
mesh_el = geometry_el.find("mesh")
|
|
|
|
|
|
|
|
# Get positions and UVs
|
|
# Get positions and UVs
|
|
|
- (positions_float_array, positions_offset, uvs_float_array, uvs_offset) = \
|
|
|
|
|
|
|
+ (positions_vec_array, positions_offset, uvs_float_array, uvs_offset) = \
|
|
|
get_positions_and_uvs(mesh_el)
|
|
get_positions_and_uvs(mesh_el)
|
|
|
|
|
|
|
|
# get polylist
|
|
# get polylist
|
|
@@ -199,21 +212,20 @@ def parse_geometry(geometry_el):
|
|
|
# Get the positions for each vertex
|
|
# Get the positions for each vertex
|
|
|
for vi in range(0, 3):
|
|
for vi in range(0, 3):
|
|
|
# index = p[fi][vi][positions_offset]
|
|
# index = p[fi][vi][positions_offset]
|
|
|
- index = p[fi * 3 * inputs_count + vi * inputs_count
|
|
|
|
|
|
|
+ pindex = p[fi * 3 * inputs_count + vi * inputs_count
|
|
|
+ positions_offset]
|
|
+ positions_offset]
|
|
|
|
|
|
|
|
- pos = Vector(positions_float_array[index * 3],
|
|
|
|
|
- positions_float_array[index * 3 + 1],
|
|
|
|
|
- positions_float_array[index * 3 + 2])
|
|
|
|
|
|
|
+ pos = positions_vec_array[pindex]
|
|
|
|
|
|
|
|
- index = p[fi * 3 * inputs_count + vi * inputs_count + uvs_offset]
|
|
|
|
|
|
|
+ uvindex = p[fi * 3 * inputs_count + vi * inputs_count + uvs_offset]
|
|
|
|
|
|
|
|
- uv = Vector(uvs_float_array[index * 2],
|
|
|
|
|
- uvs_float_array[index * 2 + 1], 0.0)
|
|
|
|
|
|
|
+ uv = Vector(uvs_float_array[uvindex * 2],
|
|
|
|
|
+ uvs_float_array[uvindex * 2 + 1], 0.0)
|
|
|
|
|
|
|
|
vert = Vertex()
|
|
vert = Vertex()
|
|
|
vert.position = pos
|
|
vert.position = pos
|
|
|
vert.uv = uv
|
|
vert.uv = uv
|
|
|
|
|
+ vert.index = pindex
|
|
|
|
|
|
|
|
i = search_in_array(verts, vert)
|
|
i = search_in_array(verts, vert)
|
|
|
if i == -1:
|
|
if i == -1:
|
|
@@ -228,55 +240,12 @@ def parse_geometry(geometry_el):
|
|
|
geom.indices = indices
|
|
geom.indices = indices
|
|
|
geom.name = geom_name
|
|
geom.name = geom_name
|
|
|
geom.id = geom_id
|
|
geom.id = geom_id
|
|
|
|
|
+ geom.vert_positions = positions_vec_array
|
|
|
|
|
|
|
|
print("------ Number of verts: %d" % len(geom.vertices))
|
|
print("------ Number of verts: %d" % len(geom.vertices))
|
|
|
print("------ Number of faces: %d" % (len(geom.indices) / 3))
|
|
print("------ Number of faces: %d" % (len(geom.indices) / 3))
|
|
|
return geom
|
|
return geom
|
|
|
|
|
|
|
|
-def write_mesh(mesh, directory, flip):
|
|
|
|
|
- """ Write mesh to file """
|
|
|
|
|
- filename = directory + "/" + mesh.name + ".mesh"
|
|
|
|
|
- print("---- Writing file: %s" % filename)
|
|
|
|
|
- f = open(filename, "wb")
|
|
|
|
|
-
|
|
|
|
|
- # Magic
|
|
|
|
|
- buff = pack("8s", b"ANKIMESH")
|
|
|
|
|
-
|
|
|
|
|
- # Mesh name
|
|
|
|
|
- buff += pack("I" + str(len(mesh.name)) + "s", len(mesh.name),
|
|
|
|
|
- mesh.name.encode("utf-8"))
|
|
|
|
|
-
|
|
|
|
|
- # Verts num
|
|
|
|
|
- buff += pack("I", len(mesh.vertices))
|
|
|
|
|
-
|
|
|
|
|
- # Verts
|
|
|
|
|
- if flip:
|
|
|
|
|
- for vert in mesh.vertices:
|
|
|
|
|
- buff += pack("fff", vert.position.x, vert.position.z,
|
|
|
|
|
- -vert.position.y)
|
|
|
|
|
- else:
|
|
|
|
|
- for vert in mesh.vertices:
|
|
|
|
|
- buff += pack("fff", vert.position.x, vert.position.y,
|
|
|
|
|
- vert.position.z)
|
|
|
|
|
-
|
|
|
|
|
- # Tris num
|
|
|
|
|
- buff += pack("I", int(len(mesh.indices) / 3))
|
|
|
|
|
-
|
|
|
|
|
- # Indices
|
|
|
|
|
- for i in mesh.indices:
|
|
|
|
|
- buff += pack("I", int(i))
|
|
|
|
|
-
|
|
|
|
|
- # Tex coords
|
|
|
|
|
- buff += pack("I", len(mesh.vertices))
|
|
|
|
|
- for vert in mesh.vertices:
|
|
|
|
|
- buff += pack("ff", vert.uv.x, vert.uv.y)
|
|
|
|
|
-
|
|
|
|
|
- # Vert weight
|
|
|
|
|
- buff += pack("I", 0)
|
|
|
|
|
-
|
|
|
|
|
- f.write(buff)
|
|
|
|
|
- f.close()
|
|
|
|
|
-
|
|
|
|
|
def update_mesh_with_vertex_weights(mesh, skin_el):
|
|
def update_mesh_with_vertex_weights(mesh, skin_el):
|
|
|
""" XXX """
|
|
""" XXX """
|
|
|
print("---- Updating with skin information: %s" % mesh.name)
|
|
print("---- Updating with skin information: %s" % mesh.name)
|
|
@@ -305,8 +274,8 @@ def update_mesh_with_vertex_weights(mesh, skin_el):
|
|
|
# Now find the joint names and the weights
|
|
# Now find the joint names and the weights
|
|
|
joint_names = None
|
|
joint_names = None
|
|
|
joint_names_offset = -1
|
|
joint_names_offset = -1
|
|
|
- weights = None
|
|
|
|
|
- weights_offset = -1
|
|
|
|
|
|
|
+ weight_arr = None
|
|
|
|
|
+ weight_arr_offset = -1
|
|
|
|
|
|
|
|
vertex_weights_el = skin_el.find("vertex_weights")
|
|
vertex_weights_el = skin_el.find("vertex_weights")
|
|
|
input_elarr = vertex_weights_el.findall("input")
|
|
input_elarr = vertex_weights_el.findall("input")
|
|
@@ -323,8 +292,8 @@ def update_mesh_with_vertex_weights(mesh, skin_el):
|
|
|
joint_names_offset = offset
|
|
joint_names_offset = offset
|
|
|
print("------ Found bone names")
|
|
print("------ Found bone names")
|
|
|
elif semantic == "WEIGHT":
|
|
elif semantic == "WEIGHT":
|
|
|
- weights = source_array
|
|
|
|
|
- weights_offset = offset
|
|
|
|
|
|
|
+ weight_arr = source_array
|
|
|
|
|
+ weight_arr_offset = offset
|
|
|
print("------ Found weights")
|
|
print("------ Found weights")
|
|
|
else:
|
|
else:
|
|
|
raise Exception("Unrecognized semantic: %s" % semantic)
|
|
raise Exception("Unrecognized semantic: %s" % semantic)
|
|
@@ -347,16 +316,108 @@ def update_mesh_with_vertex_weights(mesh, skin_el):
|
|
|
if token:
|
|
if token:
|
|
|
v.append(int(token))
|
|
v.append(int(token))
|
|
|
|
|
|
|
|
|
|
+ # Do a sanity check because we made an assumption
|
|
|
|
|
+ if len(vcount) != len(mesh.vert_positions):
|
|
|
|
|
+ raise Exception("Wrong assumption made")
|
|
|
|
|
+
|
|
|
# Now that you have all do some magic... connect them
|
|
# Now that you have all do some magic... connect them
|
|
|
- """for vert_id in range(len(vcount)):
|
|
|
|
|
- vc = vcount[vert_id]
|
|
|
|
|
- vert = mesh.ver
|
|
|
|
|
- for """
|
|
|
|
|
|
|
+ #
|
|
|
|
|
+
|
|
|
|
|
+ # For every vert
|
|
|
|
|
+ other_index = 0
|
|
|
|
|
+ for vert_id in range(len(vcount)):
|
|
|
|
|
+ bones_in_vert = vcount[vert_id]
|
|
|
|
|
+
|
|
|
|
|
+ if bones_in_vert > 4:
|
|
|
|
|
+ raise Exception("You cannot have more than 4 bones per vertex")
|
|
|
|
|
+
|
|
|
|
|
+ if bones_in_vert == 0:
|
|
|
|
|
+ print("------ *WARNING* Vertex does not have bones: %d" % vert_id)
|
|
|
|
|
+
|
|
|
|
|
+ # Get weigths and ids for the vertex
|
|
|
|
|
+ bone_ids = [-1, -1, -1, -1]
|
|
|
|
|
+ vweights = [0.0, 0.0, 0.0, 0.0]
|
|
|
|
|
+ for i in range(bones_in_vert):
|
|
|
|
|
+ bone_name_index = v[other_index * 2 + joint_names_offset]
|
|
|
|
|
+ weight_index = v[other_index * 2 + weight_arr_offset]
|
|
|
|
|
+
|
|
|
|
|
+ bone_ids[i] = bone_name_index
|
|
|
|
|
+ vweights[i] = weight_arr[weight_index]
|
|
|
|
|
+
|
|
|
|
|
+ other_index += 1
|
|
|
|
|
+
|
|
|
|
|
+ # Update the vertex and the duplicates
|
|
|
|
|
+ for vert in mesh.vertices:
|
|
|
|
|
+ if vert.index != vert_id:
|
|
|
|
|
+ continue
|
|
|
|
|
+ vert.bones_count = bones_in_vert
|
|
|
|
|
+ vert.bone_ids = bone_ids
|
|
|
|
|
+ vert.weights = vweights
|
|
|
|
|
+
|
|
|
|
|
+ # Do a sanity check. Go to all verts and check if bones_count is set
|
|
|
|
|
+ for vert in mesh.vertices:
|
|
|
|
|
+ if vert.bones_count == -1:
|
|
|
|
|
+ raise Exception("Vertex skining information not set for vertex")
|
|
|
|
|
+
|
|
|
|
|
+def write_mesh(mesh, directory, flip):
|
|
|
|
|
+ """ Write mesh to file """
|
|
|
|
|
+ filename = directory + "/" + mesh.name + ".mesh"
|
|
|
|
|
+ print("---- Writing file: %s" % filename)
|
|
|
|
|
+ f = open(filename, "wb")
|
|
|
|
|
+
|
|
|
|
|
+ # Magic
|
|
|
|
|
+ buff = pack("8s", b"ANKIMESH")
|
|
|
|
|
+
|
|
|
|
|
+ # Mesh name
|
|
|
|
|
+ buff += pack("I" + str(len(mesh.name)) + "s", len(mesh.name),
|
|
|
|
|
+ mesh.name.encode("utf-8"))
|
|
|
|
|
+
|
|
|
|
|
+ # Verts num
|
|
|
|
|
+ buff += pack("I", len(mesh.vertices))
|
|
|
|
|
+
|
|
|
|
|
+ # Verts
|
|
|
|
|
+ if flip:
|
|
|
|
|
+ for vert in mesh.vertices:
|
|
|
|
|
+ buff += pack("fff", vert.position.x, vert.position.z,
|
|
|
|
|
+ -vert.position.y)
|
|
|
|
|
+ else:
|
|
|
|
|
+ for vert in mesh.vertices:
|
|
|
|
|
+ buff += pack("fff", vert.position.x, vert.position.y,
|
|
|
|
|
+ vert.position.z)
|
|
|
|
|
+
|
|
|
|
|
+ # Tris num
|
|
|
|
|
+ buff += pack("I", int(len(mesh.indices) / 3))
|
|
|
|
|
+
|
|
|
|
|
+ # Indices
|
|
|
|
|
+ for i in mesh.indices:
|
|
|
|
|
+ buff += pack("I", int(i))
|
|
|
|
|
+
|
|
|
|
|
+ # Tex coords
|
|
|
|
|
+ buff += pack("I", len(mesh.vertices))
|
|
|
|
|
+ for vert in mesh.vertices:
|
|
|
|
|
+ buff += pack("ff", vert.uv.x, vert.uv.y)
|
|
|
|
|
+
|
|
|
|
|
+ # Vert weight
|
|
|
|
|
+ if mesh.vertices[0].bones_count != -1:
|
|
|
|
|
+ buff += pack("I", len(mesh.vertices))
|
|
|
|
|
+
|
|
|
|
|
+ for vert in mesh.vertices:
|
|
|
|
|
+ buff += pack("I", vert.bones_count)
|
|
|
|
|
+ for i in range(vert.bones_count):
|
|
|
|
|
+ buff += pack("If", vert.bone_ids[i], vert.weights[i])
|
|
|
|
|
+ else:
|
|
|
|
|
+ buff += pack("I", 0)
|
|
|
|
|
+
|
|
|
|
|
+ f.write(buff)
|
|
|
|
|
+ f.close()
|
|
|
|
|
+
|
|
|
|
|
+def write_mesh_v2(mesh, directory, flip):
|
|
|
|
|
+ noop
|
|
|
|
|
|
|
|
def main():
|
|
def main():
|
|
|
(infile, outdir, flip) = parse_commandline()
|
|
(infile, outdir, flip) = parse_commandline()
|
|
|
|
|
|
|
|
- print("-- Begin!")
|
|
|
|
|
|
|
+ print("-- Begin...")
|
|
|
xml.register_namespace("", "http://www.collada.org/2005/11/COLLADASchema")
|
|
xml.register_namespace("", "http://www.collada.org/2005/11/COLLADASchema")
|
|
|
tree = xml.parse(infile)
|
|
tree = xml.parse(infile)
|
|
|
|
|
|