1
2# write a mesh in OGRE XML format
3
4import sys
5
6#import libxml2 as myxml
7import xmlout as myxml
8
9import pprint
10
11def vector_to_xml(elem, vector, coord_names):
12	for i in range(len(coord_names)):
13		coord = "%.6f" % vector[i]
14		elem.setProp(coord_names[i], coord)
15
16class ogre_writer:
17
18	def __init__(self):
19
20		self.xmldoc = myxml.newDoc("1.0")
21		if not self.xmldoc:
22			raise IOError("Unable to create doc!!!")
23
24		mesh_elem = myxml.newNode("mesh")
25		try:
26			mesh_elem.docSetRootElement(self.xmldoc)
27		except myxml.treeError:
28			pass
29		self.materials_elem = mesh_elem.newChild(None, "materials", None)
30		self.sharedgeometry_elem = mesh_elem.newChild(None, "sharedgeometry", None)
31		self.submeshes_elem = mesh_elem.newChild(None, "submeshes", None)
32
33	def add(self, mesh):
34		if mesh.shared_geometry:
35			self.add_geometry(self.sharedgeometry_elem, mesh.glverts)
36		else:
37			self.sharedgeometry_elem.setProp("vertexcount", "0")
38		for submesh in mesh.subs:
39			self.add_material(submesh.mat_data)
40			self.add_submesh(submesh, mesh.shared_geometry)
41
42	def add_material(self, mat):
43		material_elem = self.materials_elem.newChild(None, "material", None)
44		material_elem.setProp("name", mat.name)
45
46		rgba = ["red", "green", "blue", "alpha"]
47
48		ambient_elem = material_elem.newChild(None, "ambient", None)
49		vector_to_xml(ambient_elem, mat.ambient, rgba)
50
51		diffuse_elem = material_elem.newChild(None, "diffuse", None)
52		vector_to_xml(diffuse_elem, mat.diffuse, rgba)
53
54		specular_elem = material_elem.newChild(None, "specular", None)
55		vector_to_xml(specular_elem, mat.specular, rgba)
56
57		shininess_elem = material_elem.newChild(None, "shininess", None)
58		shininess_elem.setProp("value", str(mat.shininess))
59
60		texs_elem = material_elem.newChild(None, "texturelayers", None)
61		for tex in mat.textures:
62			tex_elem = texs_elem.newChild(None, "texturelayer", None)
63			tex_elem.setProp("texture", str(tex))
64
65	def add_geometry(self, geometry_elem, vertices):
66		"add given vertices to an XML element"
67
68		geometry_elem.setProp("vertexcount", str(len(vertices)))
69
70 		want_uvs = vertices[0].uv != None
71 		vb_elem = geometry_elem.newChild(None, "vertexbuffer", None)
72 		vb_elem.setProp("positions", "true")
73 		vb_elem.setProp("normals", "true")
74 		vb_elem.setProp("colours_diffuse", "false")
75 		if want_uvs:
76 			vb_elem.setProp("texture_coords", "1")
77 			vb_elem.setProp("texture_coord_dimensions_0", "2")
78 		else:
79 			vb_elem.setProp("texture_coords", "0")
80
81		try:
82			for vert in vertices:
83				vertex_elem = vb_elem.newChild(None, "vertex", None)
84
85				position_elem = vertex_elem.newChild(None, "position", None)
86				vector_to_xml(position_elem, vert.pos, ["x", "y", "z"])
87
88				normal_elem = vertex_elem.newChild(None, "normal", None)
89				vector_to_xml(normal_elem, vert.normal, ["x", "y", "z"])
90
91				if want_uvs:
92					texcoord_elem = vertex_elem.newChild(None, "texcoord", None)
93					vector_to_xml(texcoord_elem, vert.uv, ["u", "v"])
94		except:
95			pp = pprint.PrettyPrinter(indent=4,width=78)
96			pp.pprint(vertices)
97
98			raise
99
100	def add_faces(self, submesh_elem, faces):
101		faces_elem = submesh_elem.newChild(None, "faces", None)
102		faces_elem.setProp("count", str(len(faces)))
103		for face in faces:
104			face_elem = faces_elem.newChild(None, "face", None)
105			for index in range(3):
106				face_elem.setProp("v%d" % (index + 1), str(face[index]))
107
108	def add_submesh(self, submesh, use_shared):
109		submesh_elem = self.submeshes_elem.newChild(None, "submesh", None)
110		submesh_elem.setProp("material", submesh.mat_data.name)
111		if use_shared:
112			submesh_elem.setProp("usesharedvertices", "true")
113			self.add_faces(submesh_elem, submesh.gltris)
114		else:
115			submesh_elem.setProp("usesharedvertices", "false")
116			self.add_faces(submesh_elem, submesh.gltris)
117			geometry_elem = submesh_elem.newChild(None, "geometry", None)
118			self.add_geometry(geometry_elem, submesh.glverts)
119		submesh_elem.setProp("use32bitindexes", "false")
120		submesh_elem.setProp("operationtype", str("triangle_list"))
121
122	def write(self, filename):
123		self.xmldoc.saveFormatFile(filename, 1)
124		self.xmldoc.freeDoc()
125
126# Create our xml document
127def write_ogre(mesh, filename):
128	ow = ogre_writer()
129	ow.add(mesh)
130	ow.write(filename)
131
132
133
134