8 return 1.055*(l**(1/2.4))-0.055
10 def get_colormap(srgb):
19 return os.path.split(fp)[1]
26 self.show_progress = True
27 self.use_strips = True
28 self.use_degen_tris = False
30 self.separate_mesh = False
31 self.separate_tech = False
32 self.shared_resources = True
33 self.export_lods = True
35 def compute_bounding_sphere(self, obj):
36 p1 = max(((v.co, v.co.length) for v in obj.data.vertices), key=lambda x:x[1])[0]
37 p2 = max(((v.co, (v.co-p1).length) for v in obj.data.vertices), key=lambda x:x[1])[0]
39 radius = (p1-p2).length/2
40 for v in obj.data.vertices:
43 center += d*(1-radius/d.length)/2
44 radius = (radius+d.length)/2
48 def make_external_name(self, base_name, resource_name, ext, index):
49 if self.shared_resources:
50 return resource_name+ext
52 return "{}_lod{}{}".format(base_name, lod_index, ext)
56 def create_mesh_exporter(self):
57 from .export_mesh import MeshExporter
58 mesh_export = MeshExporter()
59 mesh_export.use_strips = self.use_strips
60 mesh_export.use_degen_tris = self.use_degen_tris
63 def export_to_file(self, context, out_fn):
64 obj = context.active_object
66 from .util import Progress
67 progress = Progress(self.show_progress and context)
69 path, base = os.path.split(out_fn)
70 base = os.path.splitext(base)[0]
72 meshes = self.export_object_meshes(context, obj, progress, base_name=base)
73 if self.separate_mesh:
74 for name, st in meshes.items():
75 with open(os.path.join(path, name), "w") as out_file:
77 s.write_to_file(out_file)
79 if self.separate_tech:
82 lods += [c for c in obj.children if c.lod_for_parent]
85 lod_index = l.lod_index if l.lod_for_parent else 0
88 if obj.material_slots:
89 material = obj.material_slots[0].material
92 tech_name = self.make_external_name(base, material.name, ".tech", lod_index)
93 st = self.export_object_technique(l, base_name=base)
94 with open(os.path.join(path, tech_name), "w") as out_file:
96 s.write_to_file(out_file)
97 elif material and l.override_material:
98 mat_name = self.make_external_name(base, material.name, ".mat", lod_index)
99 st = self.export_material(material)
100 with open(os.path.join(path, mat_name), "w") as out_file:
102 s.write_to_file(out_file)
104 statements = self.export_object(context, obj, progress, meshes=meshes, base_name=base)
106 with open(out_fn, "w") as out_file:
108 s.write_to_file(out_file)
110 def export_object_meshes(self, context, obj, progress, *, base_name=None):
111 if base_name is None:
116 lods += [c for c in obj.children if c.lod_for_parent]
118 from .mesh import create_mesh_from_object
119 mesh_export = self.create_mesh_exporter()
122 for i, l in enumerate(lods):
123 lod_index = l.lod_index if l.lod_for_parent else 0
124 progress.push_task_slice("LOD {}".format(lod_index), i, len(lods))
126 mesh_name = self.make_external_name(base_name, l.data.name, ".mesh", lod_index)
127 if mesh_name not in meshes:
128 mesh = create_mesh_from_object(context, l, progress)
129 meshes[mesh_name] = mesh_export.export_mesh(context, mesh, progress)
135 def export_object(self, context, obj, progress, *, meshes=None, base_name=None):
136 if base_name is None:
140 meshes = self.export_object_meshes(context, obj, progress, base_name=base_name)
143 for c in obj.children:
145 if c.lod_index>=len(lods):
146 lods += [None]*(c.lod_index+1-len(lods))
147 lods[c.lod_index] = c
149 from .datafile import Statement
152 center, radius = self.compute_bounding_sphere(obj)
153 statements.append(Statement("bounding_sphere_hint", *center, radius))
156 prev_tech = (None, None)
157 for i, l in enumerate(lods):
160 if l.data.name!=prev_mesh:
161 mesh_name = self.make_external_name(base_name, l.data.name, ".mesh", i)
162 if self.separate_mesh:
163 lod_st.append(Statement("mesh", mesh_name))
165 st = Statement("mesh")
166 st.sub = meshes[mesh_name]
169 prev_mesh = l.data.name
172 if l.material_slots and l.material_slots[0].material:
173 mat_name = l.material_slots[0].material.name
175 tech = (l.technique, mat_name)
177 tech_name = self.make_external_name(base_name, mat_name or l.name, ".tech", i)
180 st = Statement("technique")
181 st.sub = self.export_object_technique(l, base_name=base_name)
184 lod_st.append(Statement("technique", l.technique))
185 elif self.separate_tech:
186 lod_st.append(Statement("technique", tech_name))
188 st = Statement("technique")
189 st.sub = self.export_object_technique(l, base_name=base_name)
195 st = Statement("level_of_detail", i)
197 statements.append(st)
201 progress.set_progress(1.0)
205 def export_object_technique(self, obj, *, base_name=None):
206 if base_name is None:
210 if obj.material_slots:
211 material = obj.material_slots[0].material
213 from .datafile import Statement, Token
217 if not obj.inherit_tech:
220 st = Statement("inherit", obj.technique)
222 for slot in material.texture_slots:
223 if slot and slot.texture.type=="IMAGE":
224 name = image_name(slot.texture.image)
225 if slot.use_map_color_diffuse:
226 st.sub.append(Statement("texture", "diffuse_map", name))
227 elif slot.use_map_normal:
228 st.sub.append(Statement("texture", "normal_map", name))
229 if obj.override_material:
230 mat_name = self.make_external_name(base_name, material.name, ".mat", obj.lod_index)
231 st.sub.append(Statement("material", "surface", mat_name))
232 statements.append(st)
236 pass_st = Statement("pass", "")
238 st = Statement("material")
239 st.sub = self.export_material(material)
240 pass_st.sub.append(st)
242 if self.textures!="NONE":
244 for slot in material.texture_slots:
245 if slot and slot.texture.type=="IMAGE" and slot.use_map_color_diffuse:
246 diffuse_tex = slot.texture
250 st = Statement("texunit", 0)
251 if self.textures=="INLINE":
252 ss = Statement("texture2d")
253 ss.sub.append(Statement("min_filter", Token("LINEAR")))
254 ss.sub.append(Statement("storage", Token("RGBA"), tex.image.size[0], tex.image.size[1]))
256 for p in tex.image.pixels:
257 texdata += "\\x%02X"%int(p*255)
258 ss.sub.append(Statement("raw_data", texdata))
261 st.sub.append(Statement("texture", image_name(tex.image)))
262 pass_st.sub.append(st)
263 statements.append(pass_st)
267 def export_material(self, material):
268 from .datafile import Statement
271 cm = get_colormap(material.srgb_colors)
272 if any(s.use_map_color_diffuse for s in material.texture_slots if s):
273 statements.append(Statement("diffuse", 1.0, 1.0, 1.0, 1.0))
274 amb = cm(material.ambient)
275 statements.append(Statement("ambient", amb, amb, amb, 1.0))
277 diff = material.diffuse_color*material.diffuse_intensity
278 statements.append(Statement("diffuse", cm(diff.r), cm(diff.g), cm(diff.b), 1.0))
279 amb = diff*material.ambient
280 statements.append(Statement("ambient", cm(amb.r), cm(amb.g), cm(amb.b), 1.0))
281 spec = material.specular_color*material.specular_intensity
282 statements.append(Statement("specular", cm(spec.r), cm(spec.g), cm(spec.g), 1.0))
283 statements.append(Statement("shininess", material.specular_hardness))